如何从Observable集合的CollectionChanged事件中删除所有事件处理程序(不适用于Control的click事件)

时间:2017-05-15 17:01:50

标签: c# wpf event-handling

我不想为添加的每个单独的事件处理程序执行-=,而是寻找一个通用实现来删除添加到此集合的所有事件处理程序。我知道已经有一个Q / A来从Control的事件中删除事件处理程序,但是对于一般的Observable集合没有找到相同的帮助。以'string'Observable集合为例,它可以是任何类型

public class ABC 
{
    public ObservableCollection<string> MyObservableCollection
    { 
        get;
        set;
    }
}

1 个答案:

答案 0 :(得分:0)

拥有这种与类型无关的方法:

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

您可以删除这样的事件处理程序:

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
}

如您所见,您可以找到here