问题:我有一个包含对象列表的文档类。这些对象引发 SolutionExpired
、DisplayExpired
等事件。文档需要对此做出响应。
文档有时可以交换对象,但单个对象永远不应该是多个文档的“一部分”。
我的文档类包含一堆用作事件处理程序的方法。每当一个对象进入文档时,我都会使用 AddHandler
设置事件,每当一个对象从文档中删除时,我都会使用 RemoveHandler
来消除损坏。然而,在某些情况下,很难确保所有步骤都正确执行,因此我可能会得到流氓事件处理程序。
长话短说;如何删除所有指向特定方法的处理程序?请注意,我没有潜在事件源的列表,这些可以存储在任何地方。
类似于:
RemoveHandler *.SolutionExpired, AddressOf DefObj_SolutionExpired
最佳答案
您可以使用Delegate.RemoveAll()
。 (您感兴趣的部分位于 button2_Click
)
public void Form_Load(object sender, EventArgs e)
{
button1.Click += new EventHandler(button1_Click);
button1.Click += new EventHandler(button1_Click);
button2.Click += new EventHandler(button2_Click);
TestEvent += new EventHandler(Form_TestEvent);
}
event EventHandler TestEvent;
void OnTestEvent(EventArgs e)
{
if (TestEvent != null)
TestEvent(this, e);
}
void Form_TestEvent(object sender, EventArgs e)
{
MessageBox.Show("TestEvent fired");
}
void button2_Click(object sender, EventArgs e)
{
Delegate d = TestEvent as Delegate;
TestEvent = Delegate.RemoveAll(d, d) as EventHandler;
}
void button1_Click(object sender, EventArgs e)
{
OnTestEvent(EventArgs.Empty);
}
您应该注意,它不会更改您传递给它的委托(delegate)的内容,它会返回更改后的委托(delegate)。因此,您将无法更改从表单拖放到表单上的按钮上的事件,因为 button1.Click
只能有 +=
或其上使用的是 -=
,而不是 =
。这不会编译:
button1.Click = Delegate.RemoveAll(d, d) as EventHandler;
此外,请确保无论您在何处实现此操作,都要留意潜在的竞争条件。如果您从另一个线程调用的事件中删除处理程序,您最终可能会出现一些非常奇怪的行为!
关于vb.net - 一次性删除所有事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1150250/