Title: Remove all event handlers from an event in C#
If you keep track of the event handlers that have been added to an event, you can use -= to remove them. This example shows how you can remove all event handlers associated with an event if you lose track of them.
I found this technique on this Microsoft forum.
When you click the program's Add button, the following code installs several event handlers.
private void btnAdd_Click(object sender, EventArgs e)
{
btnClickMe.Click += btnClickMe_Click;
picCanvas.Click += picCanvas_Click;
picCanvas.MouseClick += picCanvas_MouseClick;
picCanvas.MouseDown += picCanvas_MouseDown;
picCanvas.MouseMove += picCanvas_MouseMove;
picCanvas.MouseUp += picCanvas_MouseUp;
txtOutput.AppendText("Added event handlers\r\n");
}
Each of the event handlers adds a message to the output text box. For example, the following code executes when you click on the PictureBox to the left of the Click Me button.
private void picCanvas_Click(object sender, EventArgs e)
{
txtOutput.AppendText("picCanvas_Click\r\n");
}
See the example for more details.
When you click the Remove button, the following code executes.
private void btnRemove_Click(object sender, EventArgs e)
{
RemoveEvent(btnClickMe, "EventClick");
RemoveEvent(picCanvas, "EventClick");
RemoveEvent(picCanvas, "EventMouseClick");
RemoveEvent(picCanvas, "EventMouseDown");
RemoveEvent(picCanvas, "EventMouseMove");
RemoveEvent(picCanvas, "EventMouseUp");
MouseIsDown = false;
txtOutput.AppendText("Removed event handlers\r\n");
}
This code mostly calls the following RemoveEvent method, passing it the names of the controls and events that the method should remove.
// Remove all event handlers from the control's named event.
private void RemoveEvent(Control ctl, string event_name)
{
FieldInfo field_info = typeof(Control).GetField(event_name,
BindingFlags.Static | BindingFlags.NonPublic);
PropertyInfo property_info = ctl.GetType().GetProperty("Events",
BindingFlags.NonPublic | BindingFlags.Instance);
object obj = field_info.GetValue(ctl);
EventHandlerList event_handlers =
(EventHandlerList)property_info.GetValue(ctl, null);
event_handlers.RemoveHandler(obj, event_handlers[obj]);
}
The RemoveEvent method is the heart of the program. It removes all event handlers assigned to the indicated event on the given control. Here's how I think it works. (Although it's pretty arcane, so I'm not absolutely sure.)
The code first uses the Control type's GetField method to get a FieldInfo object describing the event type. It then gets a PropertyInfo object holding information about the control's events.
Next the code calls the FieldInfo object's GetValue method to get an object representing the desired event for the target control. It uses the PropertyInfo object's GetValue method to get a list of event handlers for the event. It finishes by calling RemoveHandler to remove the event handlers for the event.
Download the example to experiment with it and to see additional details.
|