jtmlp
March 27, 2023, 3:59pm
1
I have a RadzenDataGrid component where I apply various filters, but when the data changes the filters get reset. I found this GitHub issue with the exact same problem. I tried the suggested fix of changing from IEnumerable to IList, but this doesn't work:
opened 11:07AM - 16 Mar 22 UTC
closed 07:19AM - 11 Apr 22 UTC
If RadzenDataGrid.Data gets a different reference as before filter values are cl… eared.
E.g. consider the following code:
```
@page "/"
@using Radzen;
@using Radzen.Blazor;
@inject DialogService DialogService
<RadzenButton Text="Open" Click=@OnOpenClick />
<RadzenDataGrid AllowFiltering="true" FilterMode="FilterMode.Simple" Data="@MyData" TItem="Employee" ColumnWidth="300px">
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" Width="140px" />
<RadzenDataGridColumn TItem="Employee" Property="LastName" Title="First Name" Width="140px" />
</Columns>
</RadzenDataGrid>
@code {
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public IEnumerable<Employee> MyData
{
get
{
yield return new Employee() { FirstName = "Peter", LastName = "Smith" };
yield return new Employee() { FirstName = "Carl", LastName = "BlaBla" };
}
}
private async Task OnOpenClick()
{
await DialogService.OpenAsync("Closeable from overlay Dialog", ds =>
@<div>
Click outside to close this Dialog
</div>, new DialogOptions() { CloseDialogOnOverlayClick = true });
}
}
```
Steps to reproduce:
1. Set the filter value for the column First Name e.g. to "Pe" so that the data grid lists only Peter.
2. Click the Open button.
3. Problem: once the dialog is open the filter value is cleared and the grid lists all items.
Note:
If the MyData property returns always the same reference, e.g. List<Employee>, even if cleared and felt before returning, the filtering works fine.
Please, could you check this behavior and provide a fix if it is an error?
Any other ideas?
Thanks.
enchev
March 28, 2023, 5:48am
2
We cannot provide any comments until we have actual code that reproduces the problem. You can use our demos to replicate your case.
jtmlp
March 28, 2023, 7:37am
3
Try this, add a filter on the grid and then click the "Change Data" button. The filter gets reset.
<RadzenButton Text="Change Data" Click=@OnChangeDataClick />
<RadzenDataGrid AllowFiltering="true" FilterMode="FilterMode.Simple" Data="@data" TItem="Employee" ColumnWidth="300px">
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" Width="140px" />
<RadzenDataGridColumn TItem="Employee" Property="LastName" Title="First Name" Width="140px" />
</Columns>
</RadzenDataGrid>
@code {
private IList<Employee> data;
protected override void OnInitialized()
{
SetData();
}
private void OnChangeDataClick()
{
SetData();
}
private void SetData()
{
data = new List<Employee>() { new Employee() { FirstName = "Peter", LastName = "Smith" }, new Employee() { FirstName = "Carl", LastName = "BlaBla" } };
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
enchev
March 28, 2023, 10:33am
4
You might need to use LoadData binding instead in such case:
@using System.Linq.Dynamic.Core
<RadzenButton Text="Change Data" Click=@OnChangeDataClick />
<RadzenDataGrid @ref=grid AllowFiltering="true" FilterMode="FilterMode.Simple" Data="@data" Count="@count" TItem="Employee" ColumnWidth="300px" LoadData="@LoadData">
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" Width="140px" />
<RadzenDataGridColumn TItem="Employee" Property="LastName" Title="First Name" Width="140px" />
</Columns>
</RadzenDataGrid>
@code {
private IList<Employee> employees = new List<Employee>() { new Employee() { FirstName = "Peter", LastName = "Smith" }, new Employee() { FirstName = "Carl", LastName = "BlaBla" } };
private IList<Employee> data;
private int count;
RadzenDataGrid<Employee> grid;
private void OnChangeDataClick()
{
SetData();
grid.Reload();
}
private void SetData()
{
data = employees;
}
private void LoadData(LoadDataArgs args)
{
var query = employees.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(args.Filter);
}
if (!string.IsNullOrEmpty(args.OrderBy))
{
query = query.OrderBy(args.OrderBy);
}
count = query.Count();
data = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
Here's a more intuitive way to fix this for anyone that runs into this issue in the future. It simply saves the current grid settings so you can reapply them as needed.
@using Radzen
@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore
@using RadzenBlazorDemos.Services
@using System.Text.Json
@inject NavigationManager NavigationManager
@inherits DbContextPage
<RadzenButton Click="@(args => Settings = null)" Text="Clear saved settings" Style="margin-bottom: 16px" />
<RadzenButton Click="@(args => NavigationManager.NavigateTo("/datagrid-save-settings", true))" Text="Reload" Style="margin-bottom: 16px" />
<RadzenDataGrid @bind-Settings="@Settings" AllowFiltering="true" AllowColumnPicking="true" AllowGrouping="true" AllowPaging="true" PageSize="4"
AllowSorting="true" AllowMultiColumnSorting="true" ShowMultiColumnSortingIndex="true"
AllowColumnResize="true" AllowColumnReorder="true" ColumnWidth="200px"
FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" Data="@employees">
<Columns>
<RadzenDataGridColumn Title="Employee" Sortable="false" Filterable="false" UniqueID="Employee">
<Template Context="data">
<RadzenImage Path="@data.Photo" Style="width: 40px; height: 40px;" class="rz-border-radius-2 rz-me-2" AlternateText="@(data.FirstName + " " + data.LastName)" />
@data.FirstName @data.LastName
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="@nameof(Employee.Title)" Title="Title" />
<RadzenDataGridColumn Property="@nameof(Employee.EmployeeID)" Title="Employee ID" />
<RadzenDataGridColumn Property="@nameof(Employee.HireDate)" Title="Hire Date" FormatString="{0:d}" />
<RadzenDataGridColumn Property="@nameof(Employee.City)" Title="City" />
<RadzenDataGridColumn Property="@nameof(Employee.Country)" Title="Country" />
</Columns>
</RadzenDataGrid>
<EventConsole @ref=@console />
@code {
IEnumerable<Employee> employees;
EventConsole console;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
employees = dbContext.Employees;
}
private DataGridSettings savedSettings;
DataGridSettings _settings;
public DataGridSettings Settings
{
get
{
return _settings;
}
set
{
if (_settings != value)
{
_settings = value;
SaveState();
}
}
}
private void LoadState() //Call this wherever the filters get lost in your original code
{
if (savedSettings != null)
{
_settings = savedSettings;
}
}
private void SaveState()
{
savedSettings = Settings;
}
}