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.57k stars 798 forks source link

Radzen data grid doesn't respect StateHasChanged event #1006

Closed SoetZombie closed 1 year ago

SoetZombie commented 1 year ago

I have used example in your docs for repro: https://blazor.radzen.com/datagrid-grouping-api

All I did was adding two buttons for manual sorting

    <button @onclick="UpdateHeading">
        Update heading
    </button>
        <button @onclick="UpdateHeading2">
        Update heading
    </button>

Describe the bug When adding buttons mentioned above, the dataGrid "breaks".

image

whereas expected look would be:

image

To Reproduce run code:

@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore

@inherits DbContextPage
    <button @onclick="UpdateHeading">
        Update heading
    </button>
        <button @onclick="UpdateHeading2">
        Update heading
    </button>
<div style="display: flex; align-items: center; margin-bottom: 16px">
    <RadzenCheckBox TriState="true" TValue="bool?" @bind-Value="@allGroupsExpanded" Name="allGroupsExpanded" Change="@ToggleGroups" />
    <RadzenLabel Text="All groups expanded by default" Component="allGroupsExpanded" Style="margin-left: 8px; margin-right: 32px; vertical-align: middle;" />
    <RadzenButton Text="Expand all groups" Click="@(args => ToggleGroups(true))" style="margin-right: 16px" Disabled=@(allGroupsExpanded == true) />
    <RadzenButton Text="Collapse all groups" Click="@(args => ToggleGroups(false))" Disabled=@(allGroupsExpanded == false) />
</div>
<RadzenDataGrid @ref=grid AllowGrouping="true" AllowFiltering="true" AllowColumnResize="true" FilterMode="FilterMode.Advanced" PageSize="5" AllowPaging="true" AllowSorting="true" 
    Data="@employees" TItem="Employee" ColumnWidth="160px" LogicalFilterOperator="LogicalFilterOperator.Or" Render="@OnRender" 
        HideGroupedColumn="true" GroupRowRender="OnGroupRowRender" GroupRowExpand="OnGroupRowExpand" GroupRowCollapse="OnGroupRowCollapse" Group="@OnGroup"
        @bind-AllGroupsExpanded="@allGroupsExpanded">
    <Columns>
        <RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="80px" TextAlign="TextAlign.Center" />
        <RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Frozen="true" Groupable="false" Width="80px" TextAlign="TextAlign.Center" >
            <Template Context="data">
                <RadzenImage Path="@data.Photo" class="rz-gravatar" />
            </Template>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
        <RadzenDataGridColumn TItem="Employee" Property="LastName" Title="Last Name"/>
        <RadzenDataGridColumn TItem="Employee" Property="Title" Title="Title" Width="200px" />
        <RadzenDataGridColumn TItem="Employee" Property="BirthDate" Title="Birth Date" FormatString="{0:d}" />
        <RadzenDataGridColumn TItem="Employee" Property="HireDate" Title="Hire Date" FormatString="{0:d}" />
        <RadzenDataGridColumn TItem="Employee" Property="Address" Title="Address" Width="200px" />
        <RadzenDataGridColumn TItem="Employee" Property="City" Title="City" />
        <RadzenDataGridColumn TItem="Employee" Property="Region" Title="Region" />
        <RadzenDataGridColumn TItem="Employee" Property="PostalCode" Title="Postal Code" />
        <RadzenDataGridColumn TItem="Employee" Property="Country" Title="Country" />
        <RadzenDataGridColumn TItem="Employee" Property="HomePhone" Title="Home Phone" />
        <RadzenDataGridColumn TItem="Employee" Property="Extension" Title="Extension" />
        <RadzenDataGridColumn TItem="Employee" Property="Notes" Title="Notes" Width="400px" />
    </Columns>
</RadzenDataGrid>

<EventConsole @ref=@console />

@code {
    bool? allGroupsExpanded;
    RadzenDataGrid<Employee> grid;

    EventConsole console;
    IEnumerable<Employee> employees;

    void UpdateHeading() {
        grid.Groups.Add(new GroupDescriptor(){ Property = "Title", SortOrder = SortOrder.Descending });
        StateHasChanged();
    }

        void UpdateHeading2() {
        grid.Groups.Add(new GroupDescriptor(){ Property = "Region", SortOrder = SortOrder.Descending });
        StateHasChanged();

    }
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        employees = dbContext.Employees;
    }

    void OnRender(DataGridRenderEventArgs<Employee> args)
    {
        if(args.FirstRender)
        {
            args.Grid.Groups.Add(new GroupDescriptor(){ Property = "Title", SortOrder = SortOrder.Descending });
            StateHasChanged();
        }
    }

    void ToggleGroups(bool? value)
    {
        allGroupsExpanded = value;
    }

    void OnGroupRowRender(GroupRowRenderEventArgs args)
    {
        if (args.FirstRender && args.Group.Data.Key == "Vice President, Sales" || allGroupsExpanded != null)
        {
            args.Expanded = allGroupsExpanded != null ? allGroupsExpanded : false;
        }
    }

    void OnGroupRowExpand(Group group)
    {
        console.Log($"Group row with key: {group.Data.Key} expanded");
    }

    void OnGroupRowCollapse(Group group)
    {
        console.Log($"Group row with key: {group.Data.Key} collapsed");
    }

    void OnGroup(DataGridColumnGroupEventArgs<Employee> args)
    {
        console.Log($"DataGrid {(args.GroupDescriptor != null ? "grouped" : "ungrouped")} by {args.Column.GetGroupProperty()}");
    }
}

Steps to reproduce the behavior:

  1. Uncheck the preselected title in grouping
  2. Click on the first button
  3. Click on the second button
  4. See error

Using grid.Reload() solves the issue, however, that seems too excessive as a solution.

Alternatively link your repo with a sample project that can be run.

Expected behavior The grouping with buttons works the same as grouping with dragging columns Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context When using the add method in the same method

    void UpdateHeading() {
        grid.Groups.Add(new GroupDescriptor(){ Property = "Title", SortOrder = SortOrder.Descending });
        grid.Groups.Add(new GroupDescriptor(){ Property = "Region", SortOrder = SortOrder.Descending });
        StateHasChanged();
    }

It works as expected, however when it's in different methods the grid breaks unless .reload() is called

enchev commented 1 year ago

Already answered in our forum: https://forum.radzen.com/t/radzen-data-grid-doesnt-respect-state-has-changed/14275/2

I’m afraid that this is how it is supposed to work.