MudBlazor/MudBlazor

MudDataGrid INotifyCollectionChanged does not work in InteractiveServer rendermode

クローズ

#10,973 opened on 2025/03/06

 (1 件のコメント) (0 件のリアクション) (0 人の担当者)C# (1,631 件のフォーク)batch import
blazor: serverbuggood first issue

Repository metrics

Stars
 (10,394 個のスター)
PR merge metrics
 (平均マージ 6d 6h) (30d で 108 merged PRs)

説明

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

コントリビューターガイド