Binding DataGridSettings loop indefinitely when using LoadData #726

Closed
opened 2026-01-29 17:42:20 +00:00 by claunia · 3 comments
Owner

Originally created by @chouteau on GitHub (Feb 8, 2023).

When using RadzenDataGrid with @bind-Settings="MyProperty" and LoadData="MyLoadDatas" it loop on MyLoadDatas indefinitely.

Because setter of Settings property of RadzenDataGrid call the Reload method when settings assessor is null

if (settings != value)
{
    settings = value;
    if (settings == null)
    {
        canSaveSettings = false;
        Groups.Clear();
        CurrentPage = 0;
        skip = 0;
        Reset(true);
        allColumns.ToList().ForEach(c =>
        {
            c.SetVisible(true);
        });
        columns = allColumns.Where(c => c.Parent == null).ToList();
        InvokeAsync(Reload); // <------------------------------------------ Here 
        canSaveSettings = true;
    }
}

Is it possible to have a public method that returns DataGridSettings value "GetDataGridSettings" and "Set..." ?

Originally created by @chouteau on GitHub (Feb 8, 2023). When using RadzenDataGrid with @bind-Settings="MyProperty" and LoadData="MyLoadDatas" it loop on MyLoadDatas indefinitely. Because setter of Settings property of RadzenDataGrid call the Reload method when settings assessor is null ```c# if (settings != value) { settings = value; if (settings == null) { canSaveSettings = false; Groups.Clear(); CurrentPage = 0; skip = 0; Reset(true); allColumns.ToList().ForEach(c => { c.SetVisible(true); }); columns = allColumns.Where(c => c.Parent == null).ToList(); InvokeAsync(Reload); // <------------------------------------------ Here canSaveSettings = true; } } ``` Is it possible to have a public method that returns DataGridSettings value "GetDataGridSettings" and "Set..." ?
Author
Owner

@enchev commented on GitHub (Feb 8, 2023):

Just combined our Settings and LoadData demos and everything worked properly:

@page "/datagrid-save-settings"
@using Radzen
@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore
@using RadzenBlazorDemos.Services
@using Microsoft.JSInterop
@using System.Text.Json
@using System.Linq.Dynamic.Core

@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager

@inherits DbContextPage

<RadzenText TextStyle="TextStyle.H3" TagName="TagName.H1" Class="my-4">
    DataGrid <strong>save settings</strong>
</RadzenText>

<RadzenExample Name="DataGridSaveSettings" Heading="false" Documentation="false">
    <p>This example shows how to save/load DataGrid state using Settings property.</p>
    <p>The state includes current page index, page size, groups and columns filter, sort, order, width and visibility.</p>
    <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" 
                    @ref="grid" IsLoading=@isLoading Count="@count" Data="@employees" LoadData="@LoadData" TItem="Employee">
        <Columns>
            <RadzenDataGridColumn TItem="Employee" Property="Photo" Title="Employee" Sortable="false" Filterable="false">
                <Template Context="data">
                    <RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px; margin-right: 8px;" />
                    @data.FirstName @data.LastName
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Employee" Property="Title" Title="Title" />
            <RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="Employee ID" />
            <RadzenDataGridColumn TItem="Employee" Property="HireDate" Title="Hire Date" FormatString="{0:d}" />
            <RadzenDataGridColumn TItem="Employee" Property="City" Title="City" />
            <RadzenDataGridColumn TItem="Employee" Property="Country" Title="Country" />
        </Columns>
    </RadzenDataGrid>
</RadzenExample>

<EventConsole @ref=@console Class="mt-4" />

@code {
    RadzenDataGrid<Employee> grid;
    int count;
    IEnumerable<Employee> employees;
    bool isLoading = false;
    EventConsole console;

    DataGridSettings _settings;
    public DataGridSettings Settings 
    { 
        get
        {
            return _settings;
        }
        set
        {
            if (_settings != value)
            {
                _settings = value;
                InvokeAsync(SaveStateAsync);
            }
        }
    }

    private async Task LoadStateAsync()
    {
        await Task.CompletedTask;

        var result = await JSRuntime.InvokeAsync<string>("window.localStorage.getItem", "Settings");
        if (!string.IsNullOrEmpty(result))
        {
            _settings = JsonSerializer.Deserialize<DataGridSettings>(result);
        }
    }

    private async Task SaveStateAsync()
    {
        await Task.CompletedTask;

        await JSRuntime.InvokeVoidAsync("eval", $@"window.localStorage.setItem('Settings', '{JsonSerializer.Serialize<DataGridSettings>(Settings)}')");
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await LoadStateAsync();
            StateHasChanged();
        }
    }

    async Task LoadData(LoadDataArgs args)
    {
        isLoading = true;

        await Task.Yield();

        // This demo is using https://dynamic-linq.net
        var query = dbContext.Employees.AsQueryable();

        if (!string.IsNullOrEmpty(args.Filter))
        {
            // Filter via the Where method
            query = query.Where(args.Filter);
        }

        if (!string.IsNullOrEmpty(args.OrderBy))
        {
            // Sort via the OrderBy method
            query = query.OrderBy(args.OrderBy);
        }

        // Important!!! Make sure the Count property of RadzenDataGrid is set.
        count = query.Count();

        // Perform paginv via Skip and Take.
        employees = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();

        isLoading = false;
    }
}

settings-loaddata

@enchev commented on GitHub (Feb 8, 2023): Just combined our Settings and LoadData demos and everything worked properly: ``` @page "/datagrid-save-settings" @using Radzen @using RadzenBlazorDemos.Data @using RadzenBlazorDemos.Models.Northwind @using Microsoft.EntityFrameworkCore @using RadzenBlazorDemos.Services @using Microsoft.JSInterop @using System.Text.Json @using System.Linq.Dynamic.Core @inject IJSRuntime JSRuntime @inject NavigationManager NavigationManager @inherits DbContextPage <RadzenText TextStyle="TextStyle.H3" TagName="TagName.H1" Class="my-4"> DataGrid <strong>save settings</strong> </RadzenText> <RadzenExample Name="DataGridSaveSettings" Heading="false" Documentation="false"> <p>This example shows how to save/load DataGrid state using Settings property.</p> <p>The state includes current page index, page size, groups and columns filter, sort, order, width and visibility.</p> <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" @ref="grid" IsLoading=@isLoading Count="@count" Data="@employees" LoadData="@LoadData" TItem="Employee"> <Columns> <RadzenDataGridColumn TItem="Employee" Property="Photo" Title="Employee" Sortable="false" Filterable="false"> <Template Context="data"> <RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px; margin-right: 8px;" /> @data.FirstName @data.LastName </Template> </RadzenDataGridColumn> <RadzenDataGridColumn TItem="Employee" Property="Title" Title="Title" /> <RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="Employee ID" /> <RadzenDataGridColumn TItem="Employee" Property="HireDate" Title="Hire Date" FormatString="{0:d}" /> <RadzenDataGridColumn TItem="Employee" Property="City" Title="City" /> <RadzenDataGridColumn TItem="Employee" Property="Country" Title="Country" /> </Columns> </RadzenDataGrid> </RadzenExample> <EventConsole @ref=@console Class="mt-4" /> @code { RadzenDataGrid<Employee> grid; int count; IEnumerable<Employee> employees; bool isLoading = false; EventConsole console; DataGridSettings _settings; public DataGridSettings Settings { get { return _settings; } set { if (_settings != value) { _settings = value; InvokeAsync(SaveStateAsync); } } } private async Task LoadStateAsync() { await Task.CompletedTask; var result = await JSRuntime.InvokeAsync<string>("window.localStorage.getItem", "Settings"); if (!string.IsNullOrEmpty(result)) { _settings = JsonSerializer.Deserialize<DataGridSettings>(result); } } private async Task SaveStateAsync() { await Task.CompletedTask; await JSRuntime.InvokeVoidAsync("eval", $@"window.localStorage.setItem('Settings', '{JsonSerializer.Serialize<DataGridSettings>(Settings)}')"); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await LoadStateAsync(); StateHasChanged(); } } async Task LoadData(LoadDataArgs args) { isLoading = true; await Task.Yield(); // This demo is using https://dynamic-linq.net var query = dbContext.Employees.AsQueryable(); if (!string.IsNullOrEmpty(args.Filter)) { // Filter via the Where method query = query.Where(args.Filter); } if (!string.IsNullOrEmpty(args.OrderBy)) { // Sort via the OrderBy method query = query.OrderBy(args.OrderBy); } // Important!!! Make sure the Count property of RadzenDataGrid is set. count = query.Count(); // Perform paginv via Skip and Take. employees = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList(); isLoading = false; } } ``` ![settings-loaddata](https://user-images.githubusercontent.com/5804953/217544127-9481eccd-4913-4398-9811-7b534bf6d465.gif)
Author
Owner

@kastroph commented on GitHub (Feb 11, 2023):

We have the same issue.

I have replicated our datagrid as much as possible with the demo code. But have been unable to replicate the issue.

I have attached a gif of the behaviour

LoadDataLoop

@kastroph commented on GitHub (Feb 11, 2023): We have the same issue. I have replicated our datagrid as much as possible with the demo code. But have been unable to replicate the issue. I have attached a gif of the behaviour ![LoadDataLoop](https://user-images.githubusercontent.com/68622811/218256029-dbbb5baf-c643-41cd-9aba-9ad4b74710b5.gif)
Author
Owner

@LoicVandersmissen commented on GitHub (Mar 2, 2023):

Hello,
I encounter the same problem as Kastroph.
And the demo on https://blazor.radzen.com/datagrid-save-settings-loaddata is freeze on the same loop.
Best regards

@LoicVandersmissen commented on GitHub (Mar 2, 2023): Hello, I encounter the same problem as Kastroph. And the demo on [https://blazor.radzen.com/datagrid-save-settings-loaddata](https://blazor.radzen.com/datagrid-save-settings-loaddata) is freeze on the same loop. Best regards
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/radzen-blazor#726