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

MVVM模式下DataGrid中CheckBox勾选时更新Amount属性问题排查

DataGrid内CheckBox状态变更未实时更新Amount属性的问题解决

你遇到的核心问题很明确:Amount这个计算属性的更新通知只绑定到了MyDataList集合本身或者MyData选中行的变化上,但当单个数据项的IsSelected(也就是CheckBox的勾选状态)改变时,你的ViewModel并没有收到这个变化的通知,自然不会触发Amount的更新——只有切换选中行时MyData变化,才会顺带更新Amount。

解决方案:监听每个数据项的属性变化

要实现CheckBox勾选时实时更新Amount,你需要在MainViewModel中监听集合里每个MyDataClass对象的PropertyChanged事件,当IsSelected属性变化时,手动触发Amount的更新通知。

修改后的MainViewModel代码

public class MainViewModel : ViewModelBase
{
    private ObservableCollection<MyDataClass> _myDataList;
    private MyDataClass _myData;

    public MainViewModel()
    {
        var list = new List<MyDataClass> {
            new MyDataClass { Description = "Item 01", Quantity = 20, IsSelected = false },
            new MyDataClass { Description = "Item 02", Quantity = 50, IsSelected = false },
            new MyDataClass { Description = "Item 03", Quantity = 60, IsSelected = false }
        };
        MyDataList = new ObservableCollection<MyDataClass>(list);
    }

    public ObservableCollection<MyDataClass> MyDataList
    {
        get => _myDataList;
        set
        {
            if (_myDataList != null)
            {
                // 先取消旧集合的所有事件订阅
                _myDataList.CollectionChanged -= OnMyDataListCollectionChanged;
                foreach (var item in _myDataList)
                {
                    item.PropertyChanged -= OnMyDataItemPropertyChanged;
                }
            }

            _myDataList = value;

            if (_myDataList != null)
            {
                // 给新集合绑定事件
                _myDataList.CollectionChanged += OnMyDataListCollectionChanged;
                foreach (var item in _myDataList)
                {
                    item.PropertyChanged += OnMyDataItemPropertyChanged;
                }
            }

            OnPropertyChanged();
            OnPropertyChanged(nameof(Amount));
        }
    }

    public MyDataClass MyData
    {
        get => _myData;
        set
        {
            _myData = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(Amount));
        }
    }

    public double Amount => MyDataList?.Where(x => x.IsSelected).Sum(x => x.Quantity) ?? 0;

    private void OnMyDataListCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // 处理集合新增项的事件订阅
        if (e.NewItems != null)
        {
            foreach (MyDataClass item in e.NewItems)
            {
                item.PropertyChanged += OnMyDataItemPropertyChanged;
            }
        }

        // 处理集合移除项的事件取消订阅
        if (e.OldItems != null)
        {
            foreach (MyDataClass item in e.OldItems)
            {
                item.PropertyChanged -= OnMyDataItemPropertyChanged;
            }
        }

        // 集合变化时也要更新Amount
        OnPropertyChanged(nameof(Amount));
    }

    private void OnMyDataItemPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // 只有当IsSelected属性变化时,才触发Amount的更新
        if (e.PropertyName == nameof(MyDataClass.IsSelected))
        {
            OnPropertyChanged(nameof(Amount));
        }
    }
}

代码说明

  1. 集合事件监听:通过CollectionChanged事件,确保集合中新增或移除数据项时,能自动为项绑定/解绑PropertyChanged事件,避免内存泄漏。
  2. 数据项属性监听:每个MyDataClass的IsSelected属性变化时,会触发OnMyDataItemPropertyChanged方法,我们在这里判断是否是IsSelected的变化,如果是,就调用OnPropertyChanged(nameof(Amount)),通知UI更新Amount的值。
  3. 空值保护:在Amount的表达式中加入?? 0,避免MyDataList为null时出现异常。

这样修改后,你勾选或取消DataGrid中的任意CheckBox,Amount都会实时更新,不用再依赖切换选中行来触发了。

内容的提问来源于stack exchange,提问作者Celso Lívero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:29:21