MudBlazor/MudBlazor

MudDataGrid INotifyCollectionChanged does not work in InteractiveServer rendermode

已关闭

#10,973 创建于 2025年3月6日

 (1 条评论) (0 个反应) (0 位负责人)C# (1,631 个派生)batch import
blazor: serverbuggood first issue

仓库指标

星标
 (10,394 个星标)
PR 合并指标
 (平均合并 6天 6小时) (30 天内合并 108 个 PR)

描述

Things to check

  • I have searched the existing issues for this bug
  • To rule out a caching problem I made sure the bug also happens in an incognito tab

Bug type

Component

Component name

MudDataGrid

What happened?

Using MudDataGrid in InteractiveServer render mode with Items being an ObservableCollection, will not result in the grid updating when items are added via another thread.

Note this does NOT happen in a web assembly project, which is why in the try.mudblazor.com you can see it working. But if you have a project that is <Routes @rendermode="InteractiveServer" /> then it will throw an exception.

Also there is an additional bug, which is that MudDataGrid MUST have Groupable=true set for any INotifyCollectionChanged implementation to work, which is because this code is guarded by checking the Groupable property.

Expected behavior

INotifyCollectionChanged.CollectionChanged handler in MudDataGrid should InvokeAsync(..) and not require Groupable=true.

Reproduction link

https://try.mudblazor.com/snippet/mEQpYnuqCmwquNHf

Reproduction steps

@page "/"
@using System.Collections.ObjectModel

<PageTitle>Home</PageTitle>
<MudButton OnClick="Start">Start</MudButton>

<MudButton OnClick="Stop">Stop</MudButton>
<MudDataGrid Items="_items" Groupable="true">
    <Columns>
        <PropertyColumn Property="x => x.Age" />
    </Columns>
</MudDataGrid>


@code {

    private Task? _executeTask;
    private CancellationTokenSource? _stoppingCts;
    ObservableCollection<TestType> _items = new ObservableCollection<TestType>();

    private async Task Start()
    {
        await Stop();
        _stoppingCts = new CancellationTokenSource();
        _executeTask = AddItemsAsync(_stoppingCts.Token);
    }
    private async Task Stop()
    {
        if (_executeTask is null) return;
        _stoppingCts?.Cancel();
        await _executeTask;
    }
    private async Task AddItemsAsync(CancellationToken cancellationToken)
    {
        while(!cancellationToken.IsCancellationRequested)
        {
            try
            {
                _items.Add(new TestType { Age = Random.Shared.Next(1, 100) });
                await Task.Delay(2000, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
            }
            catch(Exception ex)
            {
                //InvalidOperationException will be thrown here
            }
        }
    }

    public class TestType
    {
        public int Age { get; set; }
    }
}

Relevant log output

System.InvalidOperationException: The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
   at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.RenderHandle.Render(RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
   at MudBlazor.MudDataGrid`1.GroupItems(Boolean noStateChange)
   at MudBlazor.MudDataGrid`1.<set_Items>b__278_0(Object s, NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at MudBlazorWebApp1.Components.Pages.Home.AddItemsAsync(CancellationToken cancellationToken) in C:\src\\MudBlazorWebApp1\Components\Pages\Home.razor:line 39

Version (bug)

8.3.0

Version (working)

No response

What browsers are you seeing the problem on?

Firefox

On which operating systems are you experiencing the issue?

Windows

Pull Request

  • I would like to do a Pull Request

Code of Conduct

  • I agree to follow this project's Code of Conduct

贡献者指南