Remove all event handlers from an event in C#


[example]

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 Example   Follow me on Twitter   RSS feed   Donate



About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in events and tagged , , , , , , . Bookmark the permalink.