I'm writing a Blazor server application which displays a Radzen DataGrid. This DataGrid utilizes both virtualization and a custom filter for one column of the DataGrid. Both of these features work with my DataGrid, but not at the same time. In other words, my implementation of virtualization works fine, as long as I'm not using custom filtering, and vice-versa.
I took a step back from my current application, and made a new/fresh Blazor server app, just to test my DataGrid setup. This involved using the default VS2019 Blazor server app template to create an application, add Radzen, and then add a simplified version of my virtualized, custom-filtered DataGrid. What I found is that it crashes with the same error I was seeing in my original application. Specifically, this is the error, as seen in Chrome dev tools:
Here's all of the code I added to the standard VS2019 Blazor server app. I simply replace the traditional "Counter" page with this:
@page "/counter"
<div>
<RadzenDataGrid Data="@Entries" TItem="Entry" Count="@Count"
LoadData="@LoadData"
AllowFiltering="true" AllowSorting="true" AllowPaging="false"
AllowVirtualization="true"
Style="height: calc(100vh - 200px)"
FilterMode="FilterMode.Advanced" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" LogicalFilterOperator="LogicalFilterOperator.And">
<Columns>
<RadzenDataGridColumn TItem="Entry" Property="Name" Filterable="true" Title="Name" Width="130px" />
<RadzenDataGridColumn TItem="Entry" Property="Address" Filterable="true" Title="Address" Width="240px" FilterValue="@FilterText" FilterOperator="FilterOperator.StartsWith">
<FilterTemplate>
<RadzenTextBox Name="addressEntry" @bind-Value=@FilterEntered Placeholder="Enter filter text here..." @oninput=@(args => FilterChanged(args.Value.ToString())) />
<RadzenTextBox Name="filterTextDisplay" @bind-Value=@FilterText ReadOnly="true" />
</FilterTemplate>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</div>
@code
{
private string FilterEntered { get; set; } = null;
private string FilterText { get; set; } = null;
private int Count { get; set; }
private IEnumerable<Entry> Entries { get; set; }
private List<Entry> DataSource { get; set; } = new List<Entry>();
protected override void OnInitialized()
{
for (var idx = 0; idx < 10000; idx++)
{
DataSource.Add(new Entry
{
Name = $"Name{idx+1}",
Address = $"Address{idx+1}"
});
}
}
private void FilterChanged(string filter)
{
FilterText = filter;
}
private void LoadData(LoadDataArgs args)
{
var query = DataSource.Select(e => e).AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(args.Filter);
}
if (!string.IsNullOrEmpty(args.OrderBy))
{
query = query.OrderBy(args.OrderBy);
}
Entries = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
Count = query.Count();
}
}
public class Entry
{
public string Name { get; set; }
public string Address { get; set; }
}
What I'm wanting to do is "filter as I go," in that as soon as I type something into the filter box, it is sent to the bound FilterText, triggering the LoadData method with the filter.
This works in terms of triggering LoadData with what appears to be a correct filter, but it crashes with the above error. Also, if I remove the custom filter and use standard advanced filtering, what seems to be passed in to the LoadData method is virtually identical to what is coming from my custom filter, but with no resulting crash.
The FilterChanged method may seem a bit useless (and it is in this example). However, what I'm doing in my actual application is allowing someone to type in text with an English keyboard, and as they type, the text is converted in FilterChanged into polytonic Greek, which is then used as the actual filter text value. In any case, the code above demonstrates the crash.
Does anyone have any idea from looking at the error message what might be causing this? Is this a bug, or am I doing something wrong?