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

如何捕获ObservableCollection中对象属性更新事件?CollectionChanged未触发

问题分析与解决

核心问题说明

ObservableCollection<T>.CollectionChanged 仅监听集合本身的元素增删/替换操作,不会触发集合内对象的属性变更通知。此外你的初始化代码存在逻辑错误,导致事件绑定到了被丢弃的临时集合上,进一步加剧了问题。


步骤1:修正初始化代码的事件绑定错误

你当前的代码先创建临时集合并绑定事件,随后将 BatchSensors 替换为传入的集合,导致之前的事件绑定完全失效。调整如下:

public BL_BatchContainer(string title, ObservableCollection<BatchSensor> batchSensors)
{
    InitializeComponent();
    Title = title;
    
    // 直接使用传入的集合,避免临时对象导致的事件绑定丢失
    BatchSensors = batchSensors;
    BatchSensors.CollectionChanged += OnListChanged;
    
    // 为集合中已有的元素绑定属性变更事件
    foreach (var sensor in BatchSensors)
    {
        sensor.PropertyChanged += OnSensorPropertyChanged;
    }
}

步骤2:监听集合元素的属性变更

要捕获 BatchSensor 的属性更新,需要在集合元素添加时绑定其 PropertyChanged 事件,移除时解绑:

集合变更事件处理

private void OnListChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // 解绑被移除元素的属性变更事件
    if (e.OldItems != null)
    {
        foreach (BatchSensor sensor in e.OldItems)
        {
            sensor.PropertyChanged -= OnSensorPropertyChanged;
        }
    }
    
    // 绑定新增元素的属性变更事件
    if (e.NewItems != null)
    {
        foreach (BatchSensor sensor in e.NewItems)
        {
            sensor.PropertyChanged += OnSensorPropertyChanged;
        }
    }
}

属性变更事件处理

private void OnSensorPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // 针对特定属性做处理,比如Error属性
    if (e.PropertyName == nameof(BatchSensor.Error))
    {
        var targetSensor = sender as BatchSensor;
        // 在这里编写属性变化后的业务逻辑
    }
}

步骤3:优化依赖属性的事件管理(可选但推荐)

由于 BatchSensors 是依赖属性,后续可能被外部修改。通过依赖属性的回调统一处理集合的订阅/取消订阅,避免遗漏:

修改依赖属性注册代码:

public static readonly DependencyProperty BatchSensorsProperty =
    DependencyProperty.Register(
        nameof(BatchSensors), 
        typeof(ObservableCollection<BatchSensor>), 
        typeof(BL_BatchContainer), 
        new UIPropertyMetadata(null, OnBatchSensorsChanged));

private static void OnBatchSensorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = d as BL_BatchContainer;
    var oldCollection = e.OldValue as ObservableCollection<BatchSensor>;
    var newCollection = e.NewValue as ObservableCollection<BatchSensor>;
    
    // 清理旧集合的事件绑定
    if (oldCollection != null)
    {
        oldCollection.CollectionChanged -= control.OnListChanged;
        foreach (var sensor in oldCollection)
        {
            sensor.PropertyChanged -= control.OnSensorPropertyChanged;
        }
    }
    
    // 绑定新集合的事件
    if (newCollection != null)
    {
        newCollection.CollectionChanged += control.OnListChanged;
        foreach (var sensor in newCollection)
        {
            sensor.PropertyChanged += control.OnSensorPropertyChanged;
        }
    }
}

此时初始化代码可简化为:

public BL_BatchContainer(string title, ObservableCollection<BatchSensor> batchSensors)
{
    InitializeComponent();
    Title = title;
    BatchSensors = batchSensors;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:00:28