I have found a nice example of how to remove all Click events from a form:
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]);
}
and it works well. However, what I need is to remove Closing event but I have no clue as of what to write instead of EventClick
to make it work. I tried to write EventClosing
, Closing
, but that didn't work. Thus my question is: what should be changed to make it work? Even better - I would like to find a list of all possible inputs there since I might need to remove other events like Closed
, FormClosing
, FormClosed
, etc.
P.S. a simple -=
is not possible since there can be many events attached many of them not accessible to me at all thus I wouldn't be able to remove them anyway.
As mentioned in the comments I have come up with a list of these event names with this:
typeof(Form).GetFields(BindingFlags.NonPublic | BindingFlags.Static).AsEnumerable().ToList();
Now I have a method which looks like this:
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);
}
}
}
And the usage looks like this:
myForm.DisableEvents<Form>("EVENT_CLOSING", "Closing");
Unfortunately I am yet to have come up with a way to pass a single parameter to my method.