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

WPF DataGrid修改子对象属性时ValueTotal不更新问题求助

问题描述

用Caliburn.Micro做WPF应用,DataGrid绑定的是ProductModel集合。现在遇到个问题:修改Value1或Value2里的MinValue、MaxValue时,ValueTotal不更新;但改Value3的时候,ValueTotal能正常变化。调试发现改Min/MaxValue时,Value1和Value2的Setter根本没触发。

问题根源
  1. MyModel未实现属性变更通知:MyModel的MinValue、MaxValue是自动属性,修改时不会对外通知变化,ProductModel根本不知道这些值变了,自然不会更新ValueTotal。
  2. ProductModel只监听对象替换,不监听子属性变化:ProductModel里的Value1、Value2只有在整个对象被替换时才会通知ValueTotal更新,但修改子对象的Min/MaxValue时,父对象感知不到。
  3. XAML绑定大小写不匹配:WPF绑定区分大小写,ProductModel的属性是Value1/Value2/Value3,但XAML里写的是小写的value1/value2/value3,这会导致绑定失效,甚至可能连初始值都显示不对。
  4. ProductModel里Value2的字段有笔误:代码里get { return _c_value2; }和__value2 = value;都是错误的,应该是_value2,会引发运行时错误。
解决步骤

1. 给MyModel加上属性变更通知

直接继承Caliburn.Micro的PropertyChangedBase,省得自己手动实现INotifyPropertyChanged:

public class MyModel : PropertyChangedBase
{
    private double _minValue;
    private double _maxValue;

    public double MinValue
    {
        get => _minValue;
        set
        {
            _minValue = value;
            NotifyOfPropertyChange();
        }
    }

    public double MaxValue
    {
        get => _maxValue;
        set
        {
            _maxValue = value;
            NotifyOfPropertyChange();
        }
    }
}

2. 修改ProductModel,监听子对象的属性变化

在ProductModel里,给Value1、Value2赋值时订阅它们的PropertyChanged事件,这样子对象的Min/MaxValue变了,父对象就能收到通知并更新ValueTotal;同时修正Value2的字段笔误:

public class ProductModel : Screen
{
    private MyModel _value1 = new MyModel();
    private MyModel _value2 = new MyModel();
    private double _value3;

    public double ValueTotal 
    { 
        get
        {
            var sumMaxValues = _value1.MaxValue + _value2.MaxValue;
            var sumMinValues = _value1.MinValue + _value2.MinValue;
            return (sumMaxValues + sumMinValues) / 2;
        } 
    }

    public MyModel Value1
    {
        get => _value1;
        set
        {
            // 取消旧对象的事件订阅,防止内存泄漏
            if (_value1 != null)
                _value1.PropertyChanged -= OnMyModelPropertyChanged;
            
            _value1 = value;
            
            // 给新对象订阅事件
            if (_value1 != null)
                _value1.PropertyChanged += OnMyModelPropertyChanged;
            
            NotifyOfPropertyChange(() => ValueTotal);
        }
    }

    public MyModel Value2
    {
        get => _value2;
        set
        {
            if (_value2 != null)
                _value2.PropertyChanged -= OnMyModelPropertyChanged;
            
            _value2 = value;
            
            if (_value2 != null)
                _value2.PropertyChanged += OnMyModelPropertyChanged;
            
            NotifyOfPropertyChange(() => ValueTotal);
        }
    }

    public double Value3
    {
        get => _value3;
        set 
        { 
            _value3 = value;
            NotifyOfPropertyChange(() => ValueTotal);         
        }
    }

    // 子对象属性变化时,通知ValueTotal更新
    private void OnMyModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // 只关心MinValue和MaxValue的变化
        if (e.PropertyName == nameof(MyModel.MinValue) || e.PropertyName == nameof(MyModel.MaxValue))
        {
            NotifyOfPropertyChange(() => ValueTotal);
        }
    }

    // 页面关闭时清理事件订阅,避免内存泄漏
    protected override void OnDeactivate(bool close)
    {
        if (_value1 != null)
            _value1.PropertyChanged -= OnMyModelPropertyChanged;
        if (_value2 != null)
            _value2.PropertyChanged -= OnMyModelPropertyChanged;
        base.OnDeactivate(close);
    }
}

3. 修正XAML绑定的大小写错误

把XAML里所有小写的value1/value2/value3改成大写开头的Value1/Value2/Value3,比如:

<!-- 原来的错误绑定 -->
<TextBlock Text="{Binding value1.MaxValue, StringFormat='{}{0:0.00}'}" />
<!-- 修正后的正确绑定 -->
<TextBlock Text="{Binding Value1.MaxValue, StringFormat='{}{0:0.00}'}" />

CellEditingTemplate里的TextBox绑定也要做同样修改,不然编辑时无法把值正确同步到ViewModel。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:04:56