Question

What I am trying to achive is, to add an Extenion Method to ObservableCollection which will help to remove all CollectionChanged subscribers. Here is the code. HOwever I get some error since I am not able to access the GetInvocationList from CollectionChanged.

How can I do that?

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;                        
                }
            }
        }

    }

Is there any alternative to achieve this?

Was it helpful?

Solution

You can not access the invocation list of an event from outside the class itself.

What you can do is wrap the original collection and maintain the event inside this class:

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);
    }
}

Then you can access the invocation list in your custom collection (just the basic pattern, not "production code"!).

But I just saw that the event is marked virtual, so it may works even easier (not tested, as never done):

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();
     }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top