radzenhq / radzen-blazor

Radzen Blazor is a set of 90+ free native Blazor UI components packed with DataGrid, Scheduler, Charts and robust theming including Material design and FluentUI.
https://www.radzen.com
MIT License
3.52k stars 786 forks source link

DataGrid Settings do not reload if missing AllowColumnResize property. #1733

Closed altman-80 closed 19 hours ago

altman-80 commented 4 days ago

See the example code below. I have modified the Radzen example code so that the reload button just clears and reloads the data object. Upon doing this the Saved DataGrid settings are lost. For example, if I Sort by a column and then hit reload, the sort is not reapplied after reloading.

If you add the property AllowColumnResize="true" or if you add AllowColumnReorder="true" to the RadzenDataGrid properties then the gridsettings load after reloading. There may be other settings that fix it but I just noticed including one of these 2 seems to make it work.

To Reproduce Steps to reproduce the behavior:

  1. Sort by a column (any column)
  2. Click on Reload Button
  3. Notice the Column you sorted on is not sorted anymore, the settings was lost
  4. Now change the code and add AllowColumnResize="true" to the RadzenDataGrid properties
  5. Re run same procedure and notice that the column stays sorted this time.
@using Radzen
@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore
@using RadzenBlazorDemos.Services
@using Microsoft.JSInterop
@using System.Text.Json

@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager

@inherits DbContextPage

<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="ReloadData" Text="Reload" Style="margin-bottom: 16px" />
<RadzenDataGrid @bind-Settings="@Settings" Data="@employees"
                AllowFiltering="true" AllowSorting="true" FilterMode="FilterMode.Simple"
                AllowVirtualization="true" 
                FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive">
    <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;
    }

    async Task ReloadData()
    {
        employees=null;
        //mimic getting data
        await Task.Delay(2000);
        employees = dbContext.Employees;
    }

    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("window.localStorage.setItem", "Settings", JsonSerializer.Serialize<DataGridSettings>(Settings));
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await LoadStateAsync();
            StateHasChanged();
        }
    }
}
enchev commented 19 hours ago

There is a demo showing how to load settings in such case: https://blazor.radzen.com/datagrid-save-settings-loaddata Pay special attention to LoadSettings event: image