2012-02-24 24 views
7

Duplicar posible: How would that be possible to remove all event handlers of the Click event of a Button?¿Cómo eliminar todos los controladores de eventos Click?

que desea eliminar todos los controladores de eventos Click de un botón. Encontré este método en la pregunta de desbordamiento de pila 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]); 
} 

Pero esta línea siempre devuelve nulo:

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

Y este método fue escrito en 2006.

¿Hay alguna versión más reciente de este método?

Nota: Estoy trabajando con WPF y .NET 4.0.

+0

que pueda No ayuda mucho por qué está volviendo nulo, pero @JonSkeet tiene una muy buena respuesta en http://stackoverflow.com/questions/6828054/how-would-the-be-possible-to-remove-all-event-handlers -of-the-click-event-of-a sobre por qué esto no es posible sin reflexión. Quizás necesite abordar el problema de manera diferente. –

+1

¿Cuál es el problema fundamental que estás tratando de resolver/objetivo que estás tratando de lograr? – RQDQ

+0

¿Se da cuenta de que está tratando de aplicar el código de WinForms a WPF? – Douglas

Respuesta

19

A continuación es un método de utilidad muy útil para la recuperación de todos los controladores de eventos suscritos para cualquier evento enrutado:

/// <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; 
} 

Utilizando lo anterior, la implementación de su método se vuelve bastante simple:

private void RemoveClickEvent(Button b) 
{ 
    var routedEventHandlers = GetRoutedEventHandlers(b, ButtonBase.ClickEvent); 
    foreach (var routedEventHandler in routedEventHandlers) 
     b.Click -= (RoutedEventHandler)routedEventHandler.Handler; 
} 
+0

Esta es una respuesta muy útil que desafortunadamente se adjunta a una pregunta cerrada . Creo que el "duplicado" se mejoraría al proporcionar la misma respuesta allí también. – phloopy

+1

@phloopy: Buena sugerencia. Acabo de publicar una [versión mejorada] (http://stackoverflow.com/a/12618521/1149773) de la solución anterior allí. – Douglas

Cuestiones relacionadas