7

Possible Duplicate: How would that be possible to remove all event handlers of the Click event of a Button?

I want to remove all click event handlers from a button. I found this method in Stack Overflow question How to remove all event handlers from a control.

private void RemoveClickEvent(Button b)
{
    FieldInfo f1 = typeof(Control).GetField("EventClick",
                                            BindingFlags.Static |
                                            BindingFlags.NonPublic);
    object obj = f1.GetValue(b);
    PropertyInfo pi = b.GetType().GetProperty("Events",
                                              BindingFlags.NonPublic |
                                              BindingFlags.Instance);
    EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
    list.RemoveHandler(obj, list[obj]);
}

But this line always returns null:

  typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);

And this method was written in 2006.

Is there any latest version of this method?

Note: I am working with WPF and .NET 4.0.

Community
  • 1
  • 1
Hasanuzzaman
  • 1,822
  • 5
  • 36
  • 54
  • I can't help much for why that's returning null, but @JonSkeet has a pretty good answer at http://stackoverflow.com/questions/6828054/how-would-that-be-possible-to-remove-all-event-handlers-of-the-click-event-of-a on why this is not possible without reflection. Perhaps you need to approach the problem differently. – Eric Andres Feb 24 '12 at 17:07
  • 1
    What is the fundamental problem you're trying to solve / goal you're trying to accomplish? – RQDQ Feb 24 '12 at 17:53
  • You realize that you’re trying to apply WinForms code to WPF? – Douglas Feb 24 '12 at 19:07
  • see answer "Solution to remove Event handler dynamically (using reflection). Is there a better way to do this?" http://stackoverflow.com/questions/11031149/solution-to-remove-event-handler-dynamically-using-reflection-is-there-a-bett – Dinis Cruz Jun 14 '12 at 10:24

1 Answers1

20

The below is a helpful utility method for retrieving all subscribed event handlers for any routed event:

/// <summary>
/// Gets the list of routed event handlers subscribed to the specified routed event.
/// </summary>
/// <param name="element">The UI element on which the event is defined.</param>
/// <param name="routedEvent">The routed event for which to retrieve the event handlers.</param>
/// <returns>The list of subscribed routed event handlers.</returns>
public static RoutedEventHandlerInfo[] GetRoutedEventHandlers(UIElement element, RoutedEvent routedEvent)
{
    // Get the EventHandlersStore instance which holds event handlers for the specified element.
    // The EventHandlersStore class is declared as internal.
    var eventHandlersStoreProperty = typeof(UIElement).GetProperty(
        "EventHandlersStore", BindingFlags.Instance | BindingFlags.NonPublic);
    object eventHandlersStore = eventHandlersStoreProperty.GetValue(element, null);

    // Invoke the GetRoutedEventHandlers method on the EventHandlersStore instance 
    // for getting an array of the subscribed event handlers.
    var getRoutedEventHandlers = eventHandlersStore.GetType().GetMethod(
        "GetRoutedEventHandlers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
    var routedEventHandlers = (RoutedEventHandlerInfo[])getRoutedEventHandlers.Invoke(
        eventHandlersStore, new object[] { routedEvent });

    return routedEventHandlers;
}

Using the above, the implementation of your method becomes quite simple:

private void RemoveClickEvent(Button b)
{
    var routedEventHandlers = GetRoutedEventHandlers(b, ButtonBase.ClickEvent);
    foreach (var routedEventHandler in routedEventHandlers)
        b.Click -= (RoutedEventHandler)routedEventHandler.Handler;
}
Douglas
  • 53,759
  • 13
  • 140
  • 188
  • This is a very useful answer that is unfortunately attached to a closed question. I think the "duplicate" would be improved by you providing the same answer there as well. – phloopy Aug 21 '12 at 01:36
  • 1
    @phloopy: Good suggestion. I just posted an [improved version](http://stackoverflow.com/a/12618521/1149773) of the above solution there. – Douglas Sep 27 '12 at 09:48