要在控件上创建新的事件处理程序,可以这样做
c.Click += new EventHandler(mainFormButton_Click);
或者这个
c.Click += mainFormButton_Click;
要删除事件处理程序,可以这样做
c.Click -= mainFormButton_Click;
但是如何从事件中删除所有事件处理程序呢?
要在控件上创建新的事件处理程序,可以这样做
c.Click += new EventHandler(mainFormButton_Click);
或者这个
c.Click += mainFormButton_Click;
要删除事件处理程序,可以这样做
c.Click -= mainFormButton_Click;
但是如何从事件中删除所有事件处理程序呢?
当前回答
这不是对OP的回答,但我想我把它贴在这里,以防它能帮助到其他人。
/// <summary>
/// Method to remove a (single) SocketAsyncEventArgs.Completed event handler. This is
/// partially based on information found here: http://stackoverflow.com/a/91853/253938
///
/// But note that this may not be a good idea, being very .Net implementation-dependent. Note
/// in particular use of "m_Completed" instead of "Completed".
/// </summary>
private static void RemoveCompletedEventHandler(SocketAsyncEventArgs eventArgs)
{
FieldInfo fieldInfo = typeof(SocketAsyncEventArgs).GetField("m_Completed",
BindingFlags.Instance | BindingFlags.NonPublic);
eventArgs.Completed -= (EventHandler<SocketAsyncEventArgs>)fieldInfo.GetValue(eventArgs);
}
其他回答
实际上我在用这个方法,效果很好。我受到了Aeonhack写的代码的“启发”。
Public Event MyEvent()
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If MyEventEvent IsNot Nothing Then
For Each d In MyEventEvent.GetInvocationList ' If this throws an exception, try using .ToArray
RemoveHandler MyEvent, d
Next
End If
End Sub
~MyClass()
{
if (MyEventEvent != null)
{
foreach (var d in MyEventEvent.GetInvocationList())
{
MyEventEvent -= (MyEvent)d;
}
}
}
字段MyEventEvent是隐藏的,但它确实存在。
调试过程中,你可以看到d.t target是如何实际处理事件的对象,而d.m ode是如何处理事件的方法。你只需要把它拿掉。
效果很好。不再有对象因为事件处理程序而被GC。
删除不存在的事件处理程序不会造成任何损害。因此,如果您知道可能存在哪些处理程序,您可以简单地删除它们。我刚遇到过类似的情况。这在某些情况下可能会有帮助。
如:
// Add handlers...
if (something)
{
c.Click += DoesSomething;
}
else
{
c.Click += DoesSomethingElse;
}
// Remove handlers...
c.Click -= DoesSomething;
c.Click -= DoesSomethingElse;
如果你真的要这么做……这需要深思熟虑和相当长的时间。事件处理程序在控件内的事件委托映射中进行管理。你需要
在控件实例中反射并获取此映射。 迭代每个事件,获取委托 每个委托可以依次是一系列链接的事件处理程序。调用obControl。RemoveHandler(事件处理程序)
简而言之,工作量很大。在理论上是可能的。我从没试过这样的东西。
看看是否可以对订阅-退订阶段有更好的控制/纪律。
斯蒂芬是对的。这很简单:
public event EventHandler<Cles_graph_doivent_etre_redessines> les_graph_doivent_etre_redessines;
public void remove_event()
{
if (this.les_graph_doivent_etre_redessines != null)
{
foreach (EventHandler<Cles_graph_doivent_etre_redessines> F_les_graph_doivent_etre_redessines in this.les_graph_doivent_etre_redessines.GetInvocationList())
{
this.les_graph_doivent_etre_redessines -= F_les_graph_doivent_etre_redessines;
}
}
}
我讨厌这里展示的任何完整的解决方案,我现在做了一个混合和测试,为任何事件处理程序工作:
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;
}
}
}
简单!感谢Stephen Punak。
我使用它是因为我使用一个通用的本地方法来删除委托,当设置不同的委托时,在不同的情况下调用本地方法。