从存储在附加属性中的集合的CollectionChanged事件取消订阅

本文关键字:CollectionChanged 集合 事件 取消 存储 属性 | 更新日期: 2023-09-27 18:16:33

好的,所以我有一个附加属性(在静态类中声明),它将INotifyCollectionChanged属性附加到对象上。

设置属性后,我想开始监视集合的更改,然后对集合所附加的对象执行一些操作

第一次尝试:

private static void MyProperty_OnChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
{
    // We need both the dependency object, and the collection args to process the notification
    NotifyCollectionChangedEventHandler changedFunc = (sender, eventArgs) => MyProperty_OnCollectionChanged( d, sender, eventArgs );
    if( e.OldValue != null )
        e.OldValue.CollectionChanged -= changedFunc;   // Can you see the bug?
    if( e.NewValue != null )
        e.NewValue.CollectionChanged += changedFunc;
}

为了将集合附加到处理程序中的对象,我将d拉到闭包中。很简单,对吧?

嗯,我相信你可以看到这里的错误。当该集合被删除或替换为新集合时,它无法注销事件处理程序,因为changedFunc是一个具有不同闭包的新处理程序。

那么,正确的方法是什么呢?

从存储在附加属性中的集合的CollectionChanged事件取消订阅

从您的代码中,不清楚这个静态方法在哪里。

是否有某种方法可以将事件处理程序存储为它所属类的成员变量?这将是一个单独的参考,可以根据需要添加和删除。当前,每次MyProperty_OnChanged触发时,您都在构造一个新的事件处理程序。

或者,您是否可以更改集合以存储对事件处理程序的引用,以便您可以通过e.o oldvalue . oldhandler(或类似)访问它,以便您以后可以访问它?

我通过使用另一个附加属性来保存包含事件处理程序和对d的引用的私有对象来解决这个问题。实际上,我显式地创建了一个闭包类,并保留了对它的引用。

但这对我来说似乎是一个相当沉重的方法,我真的在寻找一个更优雅的解决方案。

相关文章:
  • 没有找到相关文章