You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor中为何需重复实例化List才能填充Syncfusion DataGrid?

Blazor Syncfusion DataGrid 数据更新不显示问题解析

问题场景与代码示例

以下是用于填充Syncfusion Blazor DataGrid的C#代码,网格通过绑定_monitoringDatas变量加载数据:

namespace ligprod.Client.Pages
{
    public partial class Monitoring_ligne
    {
        ...
        private Monitoring Monit;
        private List<Monitoring> _monitoringDatas;
    
        protected override async Task OnInitializedAsync()
        {
            ...
            _monitoringDatas = new List<Monitoring>();
        }
    
        Task ReceiveLidarValue(string arg)
        {          
            _monitoringDatas = new List<Monitoring>();
            Monitoring Monit = new Monitoring()
            {
                IdMonotoring = 1,
                RealProduction = false,
                Machine = "remplisseuse",
                DatePassage = DateTime.Now,
            };

            _monitoringDatas.Add(Monit);       
        }
    }
}

核心疑问

已在OnInitializedAsync()中完成_monitoringDatas的实例化,为何必须在SignalR消息触发的ReceiveLidarValue方法中重新实例化List,网格才会显示数据?

  • 移除_monitoringDatas = new List<Monitoring>();后,网格无数据显示且无报错;
  • 保留该行代码时,网格每次仅显示最新一条数据(原有内容被覆盖)。

整体流程

  1. 服务端启动后持续监听外部电子卡的MQTT消息;
  2. 客户端页面加载时,OnInitializedAsync()执行,完成_monitoringDatas实例化;
  3. 传感器检测到运动时,服务端通过SignalR Hub向客户端推送消息;
  4. 客户端接收消息触发ReceiveLidarValue(),创建Monitoring对象并添加至_monitoringDatas。

原因分析

Blazor的UI更新机制依赖组件状态变更的检测,而Syncfusion DataGrid绑定List<T>时,默认仅在集合的引用发生变化时才会触发重新渲染:

  • 当你只调用_monitoringDatas.Add(Monit)时,List的内存引用没有改变,Blazor无法检测到状态变化,因此不会通知Grid刷新数据;
  • 重新实例化_monitoringDatas = new List<Monitoring>()时,变量的引用指向了新的内存对象,Blazor检测到这个变更后,会触发组件重新渲染,Grid也就绑定了新的List数据(但旧数据会被清空,所以只能看到最新一条)。

解决方案

方案1:手动触发状态变更

在添加数据后,调用StateHasChanged()方法手动通知Blazor组件状态已更新,这样无需重新实例化List,还能保留历史数据:

Task ReceiveLidarValue(string arg)
{          
    Monitoring Monit = new Monitoring()
    {
        IdMonotoring = 1,
        RealProduction = false,
        Machine = "remplisseuse",
        DatePassage = DateTime.Now,
    };

    _monitoringDatas.Add(Monit);
    StateHasChanged(); // 手动触发UI更新
}

方案2:使用支持变更通知的集合

将List<Monitoring>替换为ObservableCollection<Monitoring>,该集合在元素添加/删除时会自动触发变更通知,无需手动调用StateHasChanged():

步骤1:修改集合类型

// 替换List为ObservableCollection
private ObservableCollection<Monitoring> _monitoringDatas;

protected override async Task OnInitializedAsync()
{
    ...
    _monitoringDatas = new ObservableCollection<Monitoring>();
}

步骤2:更新接收方法

Task ReceiveLidarValue(string arg)
{          
    Monitoring Monit = new Monitoring()
    {
        IdMonotoring = 1,
        RealProduction = false,
        Machine = "remplisseuse",
        DatePassage = DateTime.Now,
    };

    _monitoringDatas.Add(Monit); // 自动触发UI更新
}

内容的提问来源于stack exchange,提问作者Phil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:01:22