Hi Telerik team,
When I want to bind the Blazor Grid to an ExpandoObject I need to assign the FieldType. I know I have to use non-nullable types.
But I want to use nullable types (for example int?) to have a blank cell within the Grid when there is no value for it. With "typeof(int)" instead of "typeof(int?)" every empty cell shows "0" which I don't want.
Is there any chance to let FieldType accept nullable types?
Best regards,
Rayko
There is a change in the Grid behavior from version 4.6.0 to 5.0.0.
Consider the following REPL test page: https://blazorrepl.telerik.com/cSabmRPy306iPiXK18
Clicking on a Grid cell for editing will not open it for editing if there is already an open cell in edit mode on the same table row. The issue is reproduced more easily if the OnUpdate handler is empty or not defined at all.
This used to work in version 4.6.0.
When a user deletes a record that decreases the number of pages on that Grid, and then they try to edit or add a record, they get stuck in the OnCancel event handler, which gets called over and over in an endless loop.
The behavior can be seen:
Steps To Reproduce
https://blazorrepl.telerik.com/GokIvFva42BLx7yl37
1. Delete item 11. The Grid will move you to page 1.
2. Try to edit or add a new item. OnCancel will fire in a loop.
3. If OnAdd and OnEdit are not defined, the loop will occur in OnUpdate and OnCancel.
I want to compare special characters (such as umlauts) to other user input.
In the case of a sorted column, NVDA is not narrating the correct column name and narrating the incorrect Roles for the column headers.
In the case of an unsorted column, NVDA is narrating the column name twice and repeating the information.
I have a TelerikGrid that contains many columns and a DetailTemplate within it. The Grid has functionality for multiselect with a checkbox column that appears as the first column on the grid. Is it possible to move this checkbox column in front of the detail template '+' dropdown row?
===
ADMIN EDIT
===
A possible option for the time being is to create a custom expand column and manage its position as needed. See more details and an example here: How to Reorder, Lock or Resize the Hierarchy Expand/Collapse Column in Telerik Blazor Grid.
I have a TelerikGrid with Reordarable enabled inside of a TelerikWindow. Reordering of the column works fine only the drop clue is not showing. I think this is because the z-index is incorrect.
Missing drop clue:
z-index of drop clue is 10000:
z-index of window is 10002:
Please expose an option to configure the field delimiter for CSV export. I want to set semicolon as field delimiter instead of a comma.
---
ADMIN EDIT
---
Internally the Grid uses SpreadStreamProcessing library to perform the export. That said, a necessary prerequisite to implement the current enhancement is that SpreadStreamProcessing supports settings for changing the delimiter when exporting to CSV. You may vote for the item and follow it to get status email updates.
For the time being, you may customize the exported file to set the desired field separator as suggested in the Grid CSV export - change the comma field delimiter knowledge base article.
It seems that the issue appeared after upgrading to Telerik 5.0 from 4.6.
When using a Grid with a locked column and column virtualization enabled, focusing cell from that locked column breaks the layout on horizontal scrolling.
Hello,
Do you have any sample for custom group Header template.
e..g. To calculate the value of the column based on the other fields.
---
ADMIN EDIT
---
Once aggregates for all fields are exposed, we will need to provide an option to align them with the corresponding columns. This can be achieved through a GroupHeaderColumnTemplate which is targeted in a separate request.
ADMIN EDIT: Please review this thread and add your comments so we can get the community feedback on this. We have attached to this opener post a small sample that shows how to achieve this with a few lines of code, and a short video of that behavior.
Hello Team;
The Grid Popup is a great feature, but my understanding is that the Popup form ONLY shows properties that are assigned as columns to the Grid.
If true, this poses some restrictions for us. Many times we might show ONLY small # of columns in Grid, however the form requires MORE properties during ADD or UPDATE.
Is it possible that we can use two ViewModels, one for the Grid columns with less properties and one with more properties for ADD & UPDATE?
Note: If this FR is considered, perhaps we can have separate ViewModel for Update and ADD, as sometimes, ADD might require more properties to be added than later be updated.
This feature will save a lot of time to build apps that have many tables and we have to create CRUD operations
---
ADMIN EDIT
Attached to this post are a reproducible and a workaround - setting the state in OnAfterRenderAsync with a small delay, so the initial grid render happens, then it can re-render and take the filters into account.
---
We want frozen columns exactly like this:
In a Grid loaded with data made of ExpandoObject, set an aggregate GridAggregateType.Sum breaks the grouping feature while GridAggregateType Max, Min and Count work properly
Please find the attached project: in the grid on Index.razor grouping does not work, just comment Index.razor:43 to restore grouping feature
Exception message:
Error: System.InvalidOperationException: No generic method 'Sum' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.
at System.Linq.Expressions.Expression.FindMethod(Type type, String methodName, Type[] typeArgs, Expression[] args, BindingFlags flags)
at System.Linq.Expressions.Expression.Call(Type type, String methodName, Type[] typeArguments, Expression[] arguments)
at Telerik.DataSource.Expressions.EnumerableSelectorAggregateFunctionExpressionBuilder.CreateMethodCallExpression(LambdaExpression memberSelectorExpression)
at Telerik.DataSource.Expressions.EnumerableSelectorAggregateFunctionExpressionBuilder.CreateAggregateExpression()
at Telerik.DataSource.EnumerableSelectorAggregateFunction.CreateAggregateExpression(Expression enumerableExpression, Boolean liftMemberAccessToNull)
at Telerik.DataSource.Expressions.GroupDescriptorExpressionBuilder.<ProjectionPropertyValueExpressions>b__39_0(AggregateFunction f)
at System.Linq.Enumerable.SelectIListIterator`2.ToList()
at Telerik.DataSource.Expressions.GroupDescriptorExpressionBuilder.CreateProjectionInitExpression()
at Telerik.DataSource.Expressions.GroupDescriptorExpressionBuilder.CreateAggregateFunctionsProjectionMemberBinding()
at Telerik.DataSource.Expressions.QueryableAggregatesExpressionBuilder.CreateMemberBindings()+MoveNext()
at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
at System.Linq.Expressions.Expression.MemberInit(NewExpression newExpression, IEnumerable`1 bindings)
at Telerik.DataSource.Expressions.GroupDescriptorExpressionBuilder.CreateSelectBodyExpression()
at Telerik.DataSource.Expressions.GroupDescriptorExpressionBuilder.CreateSelectExpression()
at Telerik.DataSource.Expressions.GroupDescriptorExpressionBuilderBase.CreateQuery()
at Telerik.DataSource.Extensions.QueryableExtensions.Aggregate(IQueryable source, IEnumerable`1 aggregateFunctions)
at Telerik.DataSource.Extensions.QueryableExtensions.CreateDataSourceResult[TModel,TResult](IQueryable queryable, DataSourceRequest request, Func`2 selector)
at Telerik.DataSource.Extensions.QueryableExtensions.ToDataSourceResult(IQueryable queryable, DataSourceRequest request)
at Telerik.DataSource.Extensions.QueryableExtensions.ToDataSourceResult(IEnumerable enumerable, DataSourceRequest request)
at Telerik.Blazor.Data.TelerikDataSourceBase.ProcessData(IEnumerable data)
at Telerik.Blazor.Components.Common.DataBoundComponent`1.ProcessDataInternal()
at Telerik.Blazor.Components.Common.DataBoundComponent`1.ProcessDataAsync()
at Telerik.Blazor.Components.TelerikGrid`1.DataBoundProcessData()
at Telerik.Blazor.Components.TelerikGrid`1.ProcessDataAsync()
at Telerik.Blazor.Components.TelerikGrid`1.ApplyFiltersAsync()
at Telerik.Blazor.Components.TelerikGrid`1.OnFilterChange(FilterDescriptorBase filter)
at Telerik.Blazor.Components.Common.Filters.TelerikFilterHeader`1.Filter(FilterDescriptor filterDescriptor)
at Telerik.Blazor.Components.Common.Filters.TelerikFilterHeader`1.OnValueChanged(Object newValue)
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__139_0(Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteSynchronously(TaskCompletionSource`1 completion, SendOrPostCallback d, Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<.cctor>b__23_0(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteBackground(WorkItem item)
Greetings,
When using single selection mode, a row can be selected either by clicking the checkbox or by clicking on the rest of the row. There is no difference at all. Now, let's say I have a grid with multiple selection mode enabled, e.g.:
<TelerikGrid Data="listOfFoos" SelectionMode="GridSelectionMode.Multiple">
<GridColumns>
<GridCheckboxColumn SelectAll="true" SelectAllMode="GridSelectAllMode.All" />
<GridColumn Field="@nameof(Foo.Name)" Title="Name" />
</GridColumns>
</TelerikGrid>
public class Foo {
public string Name { get; set; }
}
public List<Foo> listOfFoos = [ new Foo{Name="First"}, new Foo{Name="Second"}, new Foo{Name="Third"} ];
When we click an unselected row, the behavior varies depending on where we click exactly:
This notably makes multiple selection impossible if we click on the row but not on the checkbox and gives the impression we are using single selection mode. It is especially strange if we consider the existence of the CheckBoxOnlySelection parameter of <GridCheckboxColumn> whose name suggests we can select using the rest of the row by default.
Triggering Edit in a Grid bound to a DataTable or ExpandoObject and with edit mode set to Popup throws an unhandled exception. This started to occur in 4.1.0 - the same code runs fine on 4.0.1
To reproduce:
When the Grid is databound via OnRead event, the initially displayed aggregates are wrong and take into account the first page only.
A possible workaround is to bind the Grid in OnAfterRenderAsync -
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<TelerikGrid @ref="@GridRef"
OnRead="@OnGridRead"
TItem="@Product"
Pageable="true">
<GridAggregates>
<GridAggregate Field="@nameof(Product.Name)" Aggregate="@GridAggregateType.Count" FieldType="@(typeof(System.String))" />
</GridAggregates>
<GridColumns>
<GridColumn Field="@nameof(Product.Name)" Title="Product Name">
<FooterTemplate>
@context.Count
</FooterTemplate>
</GridColumn>
<GridColumn Field="@nameof(Product.Price)" />
<GridColumn Field="@nameof(Product.ReleaseDate)" Title="Release Date" />
<GridColumn Field="@nameof(Product.Active)" />
</GridColumns>
</TelerikGrid>
@code {
TelerikGrid<Product> GridRef { get; set; }
List<Product> GridData { get; set; }
bool ShouldBindGrid { get; set; }
async Task OnGridRead(GridReadEventArgs args)
{
if (!ShouldBindGrid)
{
return;
}
await Task.Delay(200); // simulate network delay
DataSourceResult result = GridData.ToDataSourceResult(args.Request);
args.Data = result.Data;
args.Total = result.Total;
args.AggregateResults = result.AggregateResults;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
// workaround for initial Grid aggregates
ShouldBindGrid = true;
GridRef.Rebind();
StateHasChanged();
}
}
protected override void OnInitialized()
{
GridData = new List<Product>();
var rnd = new Random();
for (int i = 1; i <= 50; i++)
{
GridData.Add(new Product()
{
Id = i,
Name = "Product " + i.ToString(),
Price = (decimal)rnd.Next(1, 100),
ReleaseDate = DateTime.Now.AddDays(-rnd.Next(60, 1000)),
Active = i % 3 == 0
});
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime ReleaseDate { get; set; }
public bool Active { get; set; }
}
}
I have a Grid bound to ObservableCollection and I try to add a new record, the Grid stays in edit mode even if I click the Save button.
Workaround:
@using System.Collections.ObjectModel
@using Telerik.FontIcons
<TelerikGrid Data="@Cards"
Height="800px"
FilterMode="GridFilterMode.FilterRow"
EditMode="GridEditMode.Inline"
OnCreate="NewCard"
OnUpdate="UpdateCard"
OnDelete="DeleteCard"
ConfirmDelete="true"
@ref="@GridReference">
<GridToolBarTemplate>
<GridCommandButton Command="Add" Icon="@FontIcon.Plus">New</GridCommandButton>
</GridToolBarTemplate>
<GridColumns>
<GridColumn Field="@nameof(AdminCard.SerialNumber)" Title="Serial number" />
<GridColumn Field="@nameof(AdminCard.DisplayNumber)" Title="Display number" />
<GridColumn Field="@nameof(AdminCard.Name)" />
<GridCommandColumn Width="140px">
<GridCommandButton Command="Save" Icon="@FontIcon.Save" ShowInEdit="true" />
<GridCommandButton Command="Edit" Icon="@FontIcon.Pencil" />
<GridCommandButton Command="Delete" Icon="@FontIcon.Trash" />
<GridCommandButton Command="Cancel" Icon="@FontIcon.Cancel" ShowInEdit="true" />
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
TelerikGrid<AdminCard> GridReference { get; set; }
public ObservableCollection<AdminCard> Cards { get; set; } = new();
protected override async Task OnInitializedAsync() =>
Cards = new ObservableCollection<AdminCard>{
new AdminCard{SerialNumber="123", DisplayNumber="1234 1234", Name="Jim"}
};
private async Task NewCard(GridCommandEventArgs args)
{
AdminCard card = (AdminCard)args.Item;
Cards.Add(card);
//apply this after saving the new record to the database
var gridState = GridReference.GetState();
gridState.InsertedItem = null;
gridState.OriginalEditItem = null;
await GridReference.SetStateAsync(gridState);
}
private async Task UpdateCard(GridCommandEventArgs args)
{
AdminCard fromGrid = (AdminCard)args.Item;
AdminCard existing = Cards.Single(c => c.Id == fromGrid.Id);
existing.SerialNumber = fromGrid.SerialNumber;
existing.DisplayNumber = fromGrid.DisplayNumber;
existing.Name = fromGrid.Name;
}
private async Task DeleteCard(GridCommandEventArgs args)
{
AdminCard card = (AdminCard)args.Item;
Cards.Remove(card);
}
public class AdminCard
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public string SerialNumber { get; set; } = "";
public string DisplayNumber { get; set; } = "";
public string Name { get; set; } = "";
}
}