microsoft / fluentui-blazor

Microsoft Fluent UI Blazor components library. For use with ASP.NET Core Blazor applications
https://www.fluentui-blazor.net
MIT License
3.88k stars 377 forks source link

fix: [DataGrid] The Select All checkbox for a SelectColumn stops working after reloading data for a data grid, when the Virtualize parameter is set #2913

Closed Stephen-Lamb closed 1 week ago

Stephen-Lamb commented 2 weeks ago

🐛 Bug Report

The Select All checkbox for a SelectColumn in a data grid stops working (no longer checks row checkboxes) after reloading data for the data grid, when the Virtualize parameter is also set for the grid.

💻 Repro or Code Sample

@page "/weather"

<PageTitle>Weather</PageTitle>

<h1>Weather</h1>

<p>This component demonstrates showing data.</p>

<FluentButton OnClick="LoadGridAsync">Reload</FluentButton>

<FluentDataGrid Virtualize="true" Items=@items GridTemplateColumns="50px 1fr 1fr 1fr 1fr" TGridItem="WeatherForecast">
    <SelectColumn TGridItem="WeatherForecast" SelectMode="DataGridSelectMode.Multiple" @bind-SelectedItems="@SelectedItems" />
    <PropertyColumn Title="Date" Property="@(c => c!.Date)" Sortable="true" Align="Align.Start" />
    <PropertyColumn Title="Temp. (C)" Property="@(c => c!.TemperatureC)" Sortable="true" Align="Align.Center" />
    <PropertyColumn Title="Temp. (F)" Property="@(c => c!.TemperatureF)" Sortable="true" Align="Align.Center" />
    <PropertyColumn Title="Summary" Property="@(c => c!.Summary)" Sortable="true" Align="Align.End" />
</FluentDataGrid>

@code {
    public class WeatherForecast
    {
        public DateOnly Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }

    IQueryable<WeatherForecast>? items;
    IEnumerable<WeatherForecast> SelectedItems = Enumerable.Empty<WeatherForecast>();

    private async Task<IQueryable<WeatherForecast>> GenerateSampleGridDataAsync(int size)
    {
        // Simulate asynchronous loading to demonstrate a loading indicator
        await Task.Delay(500);

        var startDate = DateOnly.FromDateTime(DateTime.Now);
        var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
        List<WeatherForecast> newForecasts = new();
        for (int index = 0; index < size; index++)
        {
            newForecasts.Add(new WeatherForecast
                {
                    Date = startDate.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = summaries[Random.Shared.Next(summaries.Length)]
                });
        }
        return newForecasts.AsQueryable();
    }

    protected override async Task OnInitializedAsync()
    {
        await LoadGridAsync();
    }

    private async Task LoadGridAsync()
    {
        SelectedItems = Enumerable.Empty<WeatherForecast>();
        items = await GenerateSampleGridDataAsync(5);
    }
}

🤔 Expected Behavior

Checking/unchecking the Select All checkbox for the Select Column should check/uncheck row checkboxes in the grid.

😯 Current Behavior

After reloading data for a grid with the Virtualize parameter set, checking the Select All checkbox no longer selects any other checkboxes in the grid.

Image

💁 Possible Solution

🔦 Context

We have many data grids in our app, and reloading data for a grid from a backend database is a common occurrence. I would expect the Select All checkbox to continue working after reloading data for a grid.

🌍 Your Environment

Image

dvoituron commented 1 week ago

The reason seems to be that the object references are not the same after clicking on the Reload button (of course because the the GenerateSampleGridDataAsync is called).

For example, adding this debug code below the Button:

@(String.Join("; ", SelectedItems.Select(i => i.GetHashCode().ToString())))

And this new column:

<PropertyColumn Title="Hash" Property="@(c => c!.GetHashCode())" />

Image

I need to investigate how to unload the previous object references in this case.

dvoituron commented 1 week ago

I found a solution to fix this. See #2209

peek_1

Stephen-Lamb commented 1 week ago

Many thanks @dvoituron! I'll give it a test in the next release :-).