Hi, please expose a property in TelerikGrid where we can set the number of virtual columns to load in advance. A lot of times we would like to load data in advance for 5-10 columns left & right of the current viewport, so the user doesn't see empty columns while scrolling. This may apply to rows as well. It would be very helpful to have this property, please consider exposing it. Thank you.
============
ADMIN EDIT
============
The column Virtualization feature improves the Grid performance when it has a lot of columns. This does not include loading data on demand, but rather UI virtualization. All the data is retrieved and the performance optimization is achieved by rendering only the columns for the current Grid viewport. When the user scrolls horizontally the content for the other columns is rendered and while this happens, the cells appear empty. The requested parameter will control the number of columns that will be rendered in the current viewport but will not be visible until the user scrolls. Thus, the user will not see empty columns.
When storing and restoring grid state, the selected page size is not included as part of that state currently, and needs to be stored seperately.
(When using GridPagerSettings, the user can select the page size based on inputs provided to PageSizes param. This selection is not synced and will revert to default each time the grid is loaded.
I'd like for someone to be able to select all of the rows in a particular group. The main selection checkbox will just select all of the rows.
It would be nice if this also worked for sub grouping.
This feature request is to provide an option to configure the displayed format of the editor for the GridColumn. It is essential for the numeric and date editing. An alternative would be to follow the DisplayFormat parameter and reuse it in the DatePickers and NumericTextBox. However, we need to gather feedback for the required functionality from our customers.
Scenario
Rendering the grid column like so:
<GridColumn Visible="true" Field="ScalePercent" Title="Scale Percent" DisplayFormat="{0:P5}" VisibleInColumnChooser="false" />
The data in the grid column will show the 5 decimal precision. However, when we go in edit mode the value in the NumericTextBox is restricted to two decimal places.
Workaround
1. Usage of templates
2. Generic change of globalization setting for the NumericTextBox
`culture.NumberFormat.NumberDecimalDigits`
The CheckBoxList filter does not work as expected when the Grid is bound to ExpandoObject
===
ADMIN EDIT: A possible workaround is to bind the Grid with OnRead event and populate the MemberType property of the filter descriptors manually:
@using System.Dynamic
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<TelerikGrid OnRead="@OnGridRead"
TItem="@ExpandoObject"
Pageable="true"
Sortable="true"
FilterMode="@GridFilterMode.FilterMenu"
FilterMenuType="@FilterMenuType.CheckBoxList"
Height="400px">
<GridToolBarTemplate>
<GridSearchBox />
</GridToolBarTemplate>
<GridColumns>
@{
if (GridData != null && GridData.Any())
{
<GridColumn Field="PropertyInt" FieldType="@GridPropertyTypes["PropertyInt"]" />
<GridColumn Field="PropertyString" FieldType="@GridPropertyTypes["PropertyString"]" />
<GridColumn Field="PropertyGroup" FieldType="@GridPropertyTypes["PropertyString"]" />
<GridColumn Field="PropertyDate" FieldType="@GridPropertyTypes["PropertyDate"]" />
<GridColumn Field="PropertyBool" FieldType="@GridPropertyTypes["PropertyBool"]" />
}
}
</GridColumns>
</TelerikGrid>
@code {
private List<ExpandoObject> GridData { get; set; } = new List<ExpandoObject>();
private Dictionary<string, Type> GridPropertyTypes { get; set; } = new Dictionary<string, Type>() {
{ "Id", typeof(int) },
{ "PropertyInt", typeof(int) },
{ "PropertyString", typeof(string) },
{ "PropertyGroup", typeof(string) },
{ "PropertyDate", typeof(DateTime) },
{ "PropertyBool", typeof(bool) }
};
private async Task OnGridRead(GridReadEventArgs args)
{
args.Request.Filters.OfType<CompositeFilterDescriptor>()
.Each(x =>
{
x.FilterDescriptors.OfType<FilterDescriptor>()
.Each(y => y.MemberType = GridPropertyTypes[y.Member]);
});
var result = GridData.ToDataSourceResult(args.Request);
args.Data = result.Data;
args.Total = result.Total;
args.AggregateResults = result.AggregateResults;
}
protected override void OnInitialized()
{
for (int i = 1; i <= 18; i++)
{
dynamic expando = new ExpandoObject();
expando.Id = i;
expando.PropertyGroup = $"Group {(i % 3 + 1)}";
expando.PropertyInt = i;
expando.PropertyString = $"String {(char)(64 + i)}{(char)(64 + i)}";
expando.PropertyDate = DateTime.Now.AddMonths(-i);
expando.PropertyBool = i % 2 != 0;
GridData.Add(expando);
}
}
}
Description
OnRead event is triggered multiple times when the page is different from the first one and the page size is changed.
Reproduction (if bug)
1. Create a grid and set the pageable and page sizes options
2. Navigate to a page different from the first one.
3. Change the page size.
4. The OnRead event is triggered twice.
Sample REPL for reproduction.
Browser (if bug)
All
Project type (if bug)
All
Last working version of Telerik UI for Blazor (if regression)
3.5.0
I AutoFit all columns in the Grid but would like to be able to reset their width to the initial value at a later point.
===
TELERIK EDIT: Here are two workarounds for two possible scenarios:
<TelerikButton ThemeColor="@ThemeConstants.Button.ThemeColor.Primary"
OnClick="@AutoFitColumns">AutoFit Columns</TelerikButton>
<TelerikButton ThemeColor="@ThemeConstants.Button.ThemeColor.Success"
OnClick="@ResetColumns">Reset Column Widths</TelerikButton>
<TelerikGrid @ref="@GridRef"
Data="@GridData"
Reorderable="true"
Resizable="true">
<GridColumns>
<GridColumn Field="@nameof(Product.Id)" />
<GridColumn Field="@nameof(Product.Name)" />
<GridColumn Field="@nameof(Product.Category)" />
<GridColumn Field="@nameof(Product.Stock)" />
<GridColumn Field="@nameof(Product.Discontinued)" />
</GridColumns>
</TelerikGrid>
@code {
private TelerikGrid<Product>? GridRef { get; set; }
private List<Product> GridData { get; set; } = new();
private async Task AutoFitColumns()
{
if (GridRef == null)
{
return;
}
await GridRef.AutoFitAllColumnsAsync();
}
private async Task ResetColumns()
{
if (GridRef == null)
{
return;
}
var gridState = GridRef.GetState();
foreach (var columnState in gridState.ColumnStates)
{
columnState.Width = "auto;";
}
gridState.TableWidth = $"99.9{DateTime.Now.Millisecond}%"; // Set something close to 100% instead of removing the value
await GridRef.SetStateAsync(gridState);
}
protected override void OnInitialized()
{
for (int i = 1; i <= 5; i++)
{
GridData.Add(new Product()
{
Id = i,
Name = $"Product {i}",
Category = $"Category {i % 4 + 1}",
Stock = Random.Shared.Next(0, 100),
Discontinued = i % 3 == 0
});
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public int Stock { get; set; }
public bool Discontinued { get; set; }
}
}
<TelerikGrid @ref="@GridRef"
Data="@GridData"
Reorderable="true"
Resizable="true"
Width="@GridWidth"
ShowColumnMenu="true"
OnStateChanged="@( (GridStateEventArgs<Product> args) => OnGridStateChanged(args) )">
<GridColumns>
<GridCheckboxColumn SelectAll="true" />
<GridColumn Field="@nameof(Product.Id)" />
<GridColumn Field="@nameof(Product.Name)" />
<GridColumn Field="@nameof(Product.Category)" />
<GridColumn Field="@nameof(Product.Stock)" />
<GridColumn Field="@nameof(Product.Discontinued)" />
</GridColumns>
</TelerikGrid>
@code {
private TelerikGrid<Product>? GridRef { get; set; }
private List<Product> GridData { get; set; } = new();
private string GridWidth => $"{GridIntWidth}px";
private int GridIntWidth = 1000; // A pixel Grid width is required for this scenario
private int GridMaxTableIntWidth => GridIntWidth - 17; // Assuming no horizontal scrolling
private async Task OnGridStateChanged(GridStateEventArgs<Product> args)
{
if (args.PropertyName == "ColumnStates" && Double.Parse(args.GridState.TableWidth.Replace("px", "")) < GridMaxTableIntWidth)
{
args.GridState.TableWidth = $"99.9{DateTime.Now.Millisecond}%"; // Set something close to 100% instead of removing the value
int lastVisibleColumnIndex = GetLastVisibleIndex(args.GridState.ColumnStates);
args.GridState.ColumnStates.First(x => x.Index == lastVisibleColumnIndex).Width = "auto";
await GridRef!.SetStateAsync(args.GridState);
}
}
private int GetLastVisibleIndex(ICollection<GridColumnState> columnStates)
{
int index = 0;
var visibleColumnStates = columnStates.Where(x => !x.Visible.HasValue || x.Visible.Value);
foreach (var columnState in visibleColumnStates)
{
index = Math.Max(index, columnState.Index);
}
return index;
}
protected override void OnInitialized()
{
for (int i = 1; i <= 5; i++)
{
GridData.Add(new Product()
{
Id = i,
Name = $"Product {i}",
Category = $"Category {i % 4 + 1}",
Stock = Random.Shared.Next(0, 100),
Discontinued = i % 3 == 0
});
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public int Stock { get; set; }
public bool Discontinued { get; set; }
}
}
Page Down and Page Up buttons are not working until the user clicks on the scroll when virtual scrolling is enabled.
To reproduce the issue:
1. Open the following REPL example:
https://blazorrepl.telerik.com/QHYPQVFv55nHGRWV59
2. Focus on the Grid.
3. Try to scroll with the PageDown button.
===ADMIN EDIT===
Currently, we use groups for calculating all aggregates in Grid. We can optimize the process so that when there are no groups, specific aggregates are still calculated.
In this example. Select a cell in column C. Then double click on another cell in column C. The unhandled exception will show up and a null reference exception is logged in the console.
https://blazorrepl.telerik.com/QHuSQBlj170zO4u130
The exception message is:
System.InvalidOperationException: TelerikValidationComponent requires a cascading parameter of type EditContext. You can use Telerik.Blazor.Components.TelerikValidationTooltip`1[System.String] inside a EditForm or TelerikForm.
Scenario #1
I want my users to confirm the update of a cell value with the built-in Confirmation Dialog for Blazor. If I use the keyboard (Enter, Tab) to close the edit the Confirmation dialog will popup, but after closing it the Grid hangs.
Scenario #2
If I edit a cell and press enter very quickly, the grid is not able to get the new value inserted after confirming it through the dialog.
Scenario #3
If you press Enter very quickly to confirm the value for deletion, the value is not always removed.
I need to lock the "expand" column in the Grid(Locked=true).
When I scroll horizontally, the first column with the expand/collapse icon scrolls out of view. I would like a way to lock it.
Hi Telerik Support
Facing an issue with Keyboard navigation in Telerik Grid component.
When we use TAB to navigate, the grid header gets focus only for the first time. After completing one round of navigation, second time after the Toolbar buttons, if we TAB out, focus goes to the pager sections skipping the grid header part.
Pls refer the REPL sample from Telerik website:
Steps to reproduce:
1) Use ALT + W and then use TAB key to navigate
2) First focus goes to the Toolbar button (Add Product), then goes to the Grid Header and then if we TAB again focus goes to the Pager section
3) After the Pager section, if we do steps 1 and 2 again, we can see that it skips the Grid Header focus second time onwards.
Selection performance suffers if the Grid has a large page size and uses child components in column templates:
https://blazorrepl.telerik.com/QHaLcVbl25YrVZU821
This is because the Grid doesn't apply performance optimizations for templates and always re-renders them.
Please expose a setting to disable re-rendering if it's not necessary.
Hi
The reset button is not working when we use the column template with the Telerik grid. How to solve this problem? Can you please send it example for reference?
Example Link :
Working Without Column Template
=>https://demos.telerik.com/blazor-ui/grid/column-menu
Not Working With Column Template
=>https://demos.telerik.com/blazor-ui/grid/custom-column-menu
Thanks