我找到了一个很好的示例,说明如何从表单中删除所有 Click 事件:
private void RemoveClickEvent(Form c)
{
var f1 = typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);
var obj = f1.GetValue(c);
var pi = c.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
var list = (EventHandlerList)pi.GetValue(c, null);
list.RemoveHandler(obj, list[obj]);
}
它运作良好。但是,我需要的是删除Closing事件,但我不知道写什么而不是EventClick
来使它工作。我试着写EventClosing
,Closing
,但这不起作用。因此,我的问题是:应该更改什么才能使其正常工作?更好 - 我希望找到所有可能输入的列表,因为我可能需要删除其他Closed
,FormClosing
,FormClosed
等事件
P.S。一个简单的-=
是不可能的,因为可能会有许多事件附加在我身上根本无法访问,因此无论如何我都无法删除它们。
答案 0 :(得分:1)
正如评论中所提到的,我已经提出了这些事件名称的列表:
typeof(Form).GetFields(BindingFlags.NonPublic | BindingFlags.Static).AsEnumerable().ToList();
现在我有一个看起来像这样的方法:
public static class Utils
{
public static void DisableEvents<T>(this T ctrl, string officialName, string simplifiedName) where T : Control
{
var propertyInfo = ctrl.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
var eventHandlerList = propertyInfo.GetValue(ctrl, new object[] { }) as EventHandlerList;
var fieldInfo = typeof(T).GetField(officialName, BindingFlags.NonPublic | BindingFlags.Static);
var eventKey = fieldInfo.GetValue(ctrl);
var eventHandler = eventHandlerList[eventKey];
var invocationList = eventHandler.GetInvocationList();
foreach (var item in invocationList)
{
ctrl.GetType().GetEvent(simplifiedName).RemoveEventHandler(ctrl, item);
}
}
}
用法如下:
myForm.DisableEvents<Form>("EVENT_CLOSING", "Closing");
不幸的是,我还没有想出一种方法将一个参数传递给我的方法。
答案 1 :(得分:0)
根据之前的帖子,用法必须是这样的:
myForm.DisableEvents<Form>("EVENT_FORMCLOSING", "FormClosing");
myForm.DisableEvents<Form>("EVENT_FORMCLOSED", "FormClosed");