2

在你开始问我为什么要这样做之前,请记住我对 Windows.Forms 没有太多经验,此时我只是在试验。

假设我用 5 个按钮形成。就像每个按钮一样,一旦我按下它,它就会做一些事情。我发现我可以向一个事件添加多种方法,例如:

button1.Click += DoThis;
button1.Click += ButAlsoThis;

我对每个按钮都这样做了。然后我尝试创建一个方法来删除给定按钮的所有方法。像这样的东西:

public void RemoveHandlers(Button btn)
{
    //Code to remove handlers
}

那是我卡住的地方...

我希望 C# 能接受这样的事情:

btn.Click = null

但显然事件只接受'+='和'-='。

所以现在我有了这个精心设计的系统,其中有按钮和事件处理程序列表,与字典链接。然后我单独删除每个事件处理程序。它有效......但我认为应该有一个更简单的方法。

长话短说:

是否有一种简单的方法可以在不事先了解所涉及的处理程序的情况下从事件中删除所有处理程序?

编辑,感谢 Carlos Landeras,我找到了答案:

private void RemoveClickEvent(Button b)
{
    FieldInfo f1 = typeof(Control).GetField("EventClick", 
    BindingFlags.Static | BindingFlags.NonPublic);
    object obj = f1.GetValue(b);
    PropertyInfo pi = b.GetType().GetProperty("Events",  
    BindingFlags.NonPublic | BindingFlags.Instance);
    EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
    list.RemoveHandler(obj, list[obj]);
}

但我只是不想复制+粘贴,我想知道这里发生了什么。

4

2 回答 2

2
private void RemoveClickEvent(Button b)
{
    FieldInfo f1 = typeof(Control).GetField("EventClick", 
    BindingFlags.Static | BindingFlags.NonPublic);
    object obj = f1.GetValue(b);
    PropertyInfo pi = b.GetType().GetProperty("Events",  
    BindingFlags.NonPublic | BindingFlags.Instance);
    EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
    list.RemoveHandler(obj, list[obj]);
}

检查一下,这正是您正在寻找的:

如何从控件中删除所有事件处理程序

于 2013-06-04T06:39:51.790 回答
0
class Program
{
    private event EventHandler demoEvent;

    static void Main(string[] args)
    {
        Program p = new Program();
        p.demoEvent += new EventHandler(Program_DemoEvent);
        var list = p.demoEvent.GetInvocationList();
        var demoEventType = typeof(Program).GetEvent("demoEvent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        MulticastDelegate myValue = typeof(Program).GetField("demoEvent", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).GetValue(p) as MulticastDelegate;
        var invocationList = myValue.GetInvocationList();
        foreach (var handler in invocationList)
            demoEventType.RemoveEventHandler(p, handler);
    }

    static void Program_DemoEvent(object sender, EventArgs e)
    {

    }
}
于 2013-06-04T06:51:45.920 回答