ObservableCollection的扩展方法

时间:2014-04-28 14:05:36

标签: c# observablecollection

我想要实现的目的是向ObservableCollection添加扩展方法,这有助于删除所有CollectionChanged订阅者。这是代码。因为我无法从CollectionChanged访问GetInvocationList,所以我收到了一些错误。

我该怎么做?

public static void RemoveCollectionChanged<T>(this ObservableCollection<T> collection)
    {
        NotifyCollectionChangedEventHandler _event = collection.CollectionChanged;
        if (_event != null) 
        {
            foreach (NotifyCollectionChangedEventHandler handler in collection.CollectionChanged.GetInvocationList())
            {
                if (object.ReferenceEquals(handler.Target, collection))
                {
                    CollectionChanged -= handler;                        
                }
            }
        }

    }

有没有其他办法来实现这个目标?

1 个答案:

答案 0 :(得分:3)

您无法从类本身外部访问事件的调用列表。

您可以做的是包装原始集合并在此类中维护事件:

MyObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
    ObservableCollection<T> internalCollection = new ObservableCollection<T>();

    //implement collection methods as forwards to internalCollection EXCEPT the changed event
    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public MyObservableCollection()
    {
        internalCollection.CollectionChanged += (s, e) => CollectionChanged(s, e);
    }
}

然后您可以访问自定义集合中的调用列表(只是基本模式,而不是“生产代码”!)。

但我刚看到该事件已标记为virtual,因此它可能更容易工作(未经测试,从未做过):

MyObservableCollection<T> : ObservableCollection<T>
{
    private List<NotifyCollectionChangedEventHandler> changedHandlers = new List<NotifyCollectionChangedEventHandler>();

    public override event NotifyCollectionChangedEventHandler CollectionChanged
    {
        add
        {
            changedHandlers.Add(value);
            base.CollectionChanged += value;
        }
        remove
        {
            changedHandlers.Remove(value);
            base.CollectionChanged -= value;
        }
     }

     public void RemoveCollectionChanged()
     {
         foreach (var handler in changedHandlers)
             base.CollectionChanged -= handler;
         changedHandlers.Clear();
     }
}