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

在WPF中使用MVVM Toolkit监听嵌套对象的属性变化

在WPF中使用MVVM Toolkit监听嵌套对象的属性变化

嘿,我明白你想在WPF应用里用MVVM Toolkit构建一个能实时汇总“测量电流”的图表,现在遇到了嵌套对象属性变化监听的问题对吧?我来给你一步步梳理解决方案~

首先,先把你给出的代码补全(推测你写Connection类时的输入失误):

public partial class CurrentFlow : ObservableObject
{
    [ObservableProperty]
    private int _id;
    [ObservableProperty]
    private float _current;
}

public partial class Connection : CurrentFlow
{
    // 这里可以添加Connection特有的可观察属性,比如名称
    [ObservableProperty]
    private string _connectionName;
}

你的核心需求是:当CurrentFlow(或其子类Connection)的Current属性变化时,能自动汇总所有图表元素的电流值并更新UI。下面是两种实用的实现方式:

方法一:通过事件监听实现实时汇总

这种方式直观直接,适合简单场景。我们在视图模型中监听集合的变化,以及每个集合元素的PropertyChanged事件,当电流属性变化时重新计算总和。

假设你有一个主视图模型MainViewModel,代码如下:

using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;

public partial class MainViewModel : ObservableObject
{
    // 存储所有Connection实例的可观察集合
    [ObservableProperty]
    private ObservableCollection<Connection> _connections = new();

    // 汇总后的总电流,UI会自动监听这个属性的变化
    [ObservableProperty]
    private float _totalCurrent;

    public MainViewModel()
    {
        // 监听集合的添加/移除事件
        Connections.CollectionChanged += OnConnectionsCollectionChanged;
    }

    private void OnConnectionsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
    {
        // 处理被移除的元素,取消订阅它们的PropertyChanged事件
        if (e.OldItems != null)
        {
            foreach (CurrentFlow item in e.OldItems)
            {
                item.PropertyChanged -= OnCurrentFlowPropertyChanged;
            }
        }

        // 处理新增的元素,订阅它们的PropertyChanged事件
        if (e.NewItems != null)
        {
            foreach (CurrentFlow item in e.NewItems)
            {
                item.PropertyChanged += OnCurrentFlowPropertyChanged;
            }
        }

        // 集合变化后重新计算总电流
        UpdateTotalCurrent();
    }

    private void OnCurrentFlowPropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        // 仅当Current属性变化时更新总电流
        if (e.PropertyName == nameof(CurrentFlow.Current))
        {
            UpdateTotalCurrent();
        }
    }

    // 计算所有Connection的电流总和
    private void UpdateTotalCurrent()
    {
        TotalCurrent = Connections.Sum(connection => connection.Current);
    }

    // 可选:实现IDisposable接口避免内存泄漏
    public void Dispose()
    {
        foreach (var connection in Connections)
        {
            connection.PropertyChanged -= OnCurrentFlowPropertyChanged;
        }
        Connections.CollectionChanged -= OnConnectionsCollectionChanged;
    }
}

方法二:用MVVM Toolkit的Messenger实现解耦监听

如果你希望视图模型和CurrentFlow之间更解耦,可以使用MVVM Toolkit的Messenger来传递属性变化消息,适合复杂项目架构。

  1. 先在CurrentFlow中添加属性变化后的消息发送逻辑:
using CommunityToolkit.Mvvm.Messaging;

public partial class CurrentFlow : ObservableObject
{
    [ObservableProperty]
    private int _id;
    [ObservableProperty]
    private float _current;

    // MVVM Toolkit会自动生成这个部分方法,在Current属性变化时触发
    partial void OnCurrentChanged(float oldValue, float newValue)
    {
        // 发送电流变化的消息,携带变化量
        Messenger.Default.Send(new CurrentChangedMessage(this, newValue - oldValue));
    }
}

// 定义消息类
public record CurrentChangedMessage(CurrentFlow Source, float Delta);
  1. 然后在MainViewModel中订阅消息并更新总电流:
using CommunityToolkit.Mvvm.Messaging;

public partial class MainViewModel : ObservableObject
{
    [ObservableProperty]
    private ObservableCollection<Connection> _connections = new();

    [ObservableProperty]
    private float _totalCurrent;

    public MainViewModel()
    {
        // 订阅电流变化消息
        Messenger.Default.Register<CurrentChangedMessage>(this, (recipient, message) =>
        {
            TotalCurrent += message.Delta;
        });

        // 监听集合移除事件,同步减少总电流
        Connections.CollectionChanged += (sender, e) =>
        {
            if (e.OldItems != null)
            {
                TotalCurrent -= e.OldItems.Cast<CurrentFlow>().Sum(item => item.Current);
            }
            if (e.NewItems != null)
            {
                TotalCurrent += e.NewItems.Cast<CurrentFlow>().Sum(item => item.Current);
            }
        };
    }
}

你可以根据自己的项目复杂度选择合适的方式,两种方案都能实现你需要的实时电流汇总功能~

备注:内容来源于stack exchange,提问作者Freakwave

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:48:06