0

I don't want to do -= for each individual event handler added, but looking for a common implementation to remove all event handler added to this collection. I know there is already a Q/A to remove event handlers from Control's event, but don't find the same helpful for a generic Observable collection. Given 'string' Observable collection as an example, it can be of any type

public class ABC 
{
    public ObservableCollection<string> MyObservableCollection
    { 
        get;
        set;
    }
}
Milan Raval
  • 1,880
  • 1
  • 16
  • 33
  • 1
    Looks like you'll need to use reflection http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control – WithMetta May 15 '17 at 17:08
  • @ Hossein Narimani Rad: How it is duplicate, I don't found a way to do same for generic Observable collection – Milan Raval May 15 '17 at 17:13
  • You are not dealing with a generic `ObservableCollcetion` you are dealing with `ObservableCollection`. – Hossein Narimani Rad May 15 '17 at 17:49
  • It is an example, I mean to say it can be any type of observable collection, and I asked this question because I don't find any way to remove all handlers attached to collection changed event. – Milan Raval May 15 '17 at 17:52
  • 1
    See also https://stackoverflow.com/questions/460525/remove-handlers-on-disposing-object. Fact is, you should not be doing this. You should only remove handlers that you added, and if you added them, you know what the handlers are and can remove them using the normal event `remove` syntax. Note that any class can implement the `event` explicitly, which means you'll have a fragile, implementation-dependent removal at best, and a completely broken one at worst. Even the compiler provides no guarantees about the implicitly-implemented events. – Peter Duniho May 16 '17 at 00:08

1 Answers1

1

Having this type-independent method:

public static FieldInfo GetEventField(this Type type, string eventName)
{
    FieldInfo field = null;
    while (type != null)
    {
        /* Find events defined as field */
        field = type.GetField(eventName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null && (field.FieldType == typeof(MulticastDelegate) || field.FieldType.IsSubclassOf(typeof(MulticastDelegate))))
            break;

        /* Find events defined as property { add; remove; } */
        field = type.GetField("EVENT_" + eventName.ToUpper(), BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null)
            break;
        type = type.BaseType;
    }
    return field;
}

You can remove event handlers like this:

static void Main(string[] args)
{
    ObservableCollection<string> obj = new ObservableCollection<string>();

    obj.CollectionChanged += (sender, e) => { Console.WriteLine("Changed1"); };

    obj.CollectionChanged += (sender, e) => { Console.WriteLine("Changed2"); };

    obj.Add("value1");  //Changed1, Changed2 raised

    var fi = obj.GetType().GetEventField("CollectionChanged");
    if (fi == null) return;
    fi.SetValue(obj, null);  //remove all event handlers

    obj.Add("value3"); //Nothing raised
}

As you see you could find this here

Community
  • 1
  • 1
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116