NET问答: 如何从 event 中移除所有的 handler ?

咨询区

  • Carrick

我知道在 Control 上如何新建一个 Handler。


c.Click += new EventHandler(mainFormButton_Click);

或者这样


c.Click += mainFormButton_Click;

也知道如何从 event 上移除一个 handler。


c.Click -= mainFormButton_Click;

现在的疑问是:如果简单粗暴的从一个 event 上移除所有的 handler 呢?

回答区

  • azheglov

我在 MSDN 上发现了一个解决方案:https://social.msdn.microsoft.com/Forums/en-US/576f69e7-55aa-4574-8d31-417422954689/get-a-list-of-delegate-on-event?forum=csharpgeneral  比如下面的代码可以帮助你移除 button1 控件上所有的 click 事件。


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        button1.Click += button1_Click;
        button1.Click += button1_Click2;
        button2.Click += button2_Click;
    }

    private void button1_Click(object sender, EventArgs e)  => MessageBox.Show("Hello");
    private void button1_Click2(object sender, EventArgs e) => MessageBox.Show("World");
    private void button2_Click(object sender, EventArgs e)  => RemoveClickEvent(button1);

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

  • Vinicius Schneider

上面这帮人的解决方案都太复杂了,我有一个非常简单粗暴的解决办法。


public class MyMain()

    public void MyMethod() {
        AnotherClass.TheEventHandler += DoSomeThing;
    }

    private void DoSomething(object sender, EventArgs e) {
        Debug.WriteLine("I did something");
        AnotherClass.ClearAllDelegatesOfTheEventHandler();
    }

}

public static class AnotherClass {

    public static event EventHandler TheEventHandler;

    public static void ClearAllDelegatesOfTheEventHandler() {

        foreach (Delegate d in TheEventHandler.GetInvocationList())
        {
            TheEventHandler -= (EventHandler)d;
        }
    }
}

点评区

这个问题有很多的留言,有反射的,也有用 List 缓存的,其实 deletege 里面本身就有一个 list 数组,里面存放着就是那一堆 handler,所以 Vinicius Schneider 大佬提供的这种方式值得学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值