咨询区
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 大佬提供的这种方式值得学习。