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

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 大佬提供的这种方式值得学习。

以上是关于NET问答: 如何从 event 中移除所有的 handler ?的主要内容,如果未能解决你的问题,请参考以下文章

从 Android Studio 中移除项目

如何从 UITextField 中移除焦点?

如何从JavaScript对象中移除一个属性

如何观察 NSManagedObject 是不是从 managedObjectContext 中移除

如何从 MaterialCardView 中移除涟漪效应?

如何从提交按钮中移除焦点