要在控件上创建新的事件处理程序,可以这样做
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;
但是如何从事件中删除所有事件处理程序呢?
当前回答
删除按钮的所有处理程序: save.RemoveEvents ();
public static class EventExtension
{
public static void RemoveEvents<T>(this T target) where T : Control
{
var propInfo = typeof(T).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
var list = (EventHandlerList)propInfo.GetValue(target, null);
list.Dispose();
}
}
其他回答
接受的答案不完整。对于声明为{add;删除;}
下面是工作代码:
public static void ClearEventInvocations(this object obj, string eventName)
{
var fi = obj.GetType().GetEventField(eventName);
if (fi == null) return;
fi.SetValue(obj, null);
}
private static FieldInfo GetEventField(this Type type, string eventName)
{
FieldInfo field = null;
while (type != null)
{
/* Find events defined as field */
field = type.GetField(eventName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null && (field.FieldType == typeof(MulticastDelegate) || field.FieldType.IsSubclassOf(typeof(MulticastDelegate))))
break;
/* Find events defined as property { add; remove; } */
field = type.GetField("EVENT_" + eventName.ToUpper(), BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
break;
type = type.BaseType;
}
return field;
}
从删除所有事件处理程序:
Directly no, in large part because you cannot simply set the event to null. Indirectly, you could make the actual event private and create a property around it that tracks all of the delegates being added/subtracted to it. Take the following: List<EventHandler> delegates = new List<EventHandler>(); private event EventHandler MyRealEvent; public event EventHandler MyEvent { add { MyRealEvent += value; delegates.Add(value); } remove { MyRealEvent -= value; delegates.Remove(value); } } public void RemoveAllEvents() { foreach(EventHandler eh in delegates) { MyRealEvent -= eh; } delegates.Clear(); }
删除不存在的事件处理程序不会造成任何损害。因此,如果您知道可能存在哪些处理程序,您可以简单地删除它们。我刚遇到过类似的情况。这在某些情况下可能会有帮助。
如:
// Add handlers...
if (something)
{
c.Click += DoesSomething;
}
else
{
c.Click += DoesSomethingElse;
}
// Remove handlers...
c.Click -= DoesSomething;
c.Click -= DoesSomethingElse;
如果你真的要这么做……这需要深思熟虑和相当长的时间。事件处理程序在控件内的事件委托映射中进行管理。你需要
在控件实例中反射并获取此映射。 迭代每个事件,获取委托 每个委托可以依次是一系列链接的事件处理程序。调用obControl。RemoveHandler(事件处理程序)
简而言之,工作量很大。在理论上是可能的。我从没试过这样的东西。
看看是否可以对订阅-退订阶段有更好的控制/纪律。
你们对自己太苛刻了。很简单:
void OnFormClosing(object sender, FormClosingEventArgs e)
{
foreach(Delegate d in FindClicked.GetInvocationList())
{
FindClicked -= (FindClickedHandler)d;
}
}