2012-02-24 6 views
7

가능한 중복 : How would that be possible to remove all event handlers of the Click event of a Button?클릭 이벤트 핸들러를 모두 제거하는 방법은 무엇입니까?

내가 버튼에서 모든 클릭 이벤트 핸들러를 제거 할. 스택 오버플로 질문에서이 메서드를 찾았습니다 How to remove all event handlers from a control. 이 방법의 최신 버전이

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

그리고이 방법은 2006 년

작성되었습니다 :

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]); 
} 

은 그러나이 선은 항상 null이 반환?

참고 : WPF.NET 4.0으로 작업하고 있습니다.

+0

내가 할 수있는 그게 null을 돌려주는 이유에 대해 많은 도움을 주지만, @ JonSkeet은 http://stackoverflow.com/questions/6828054/how-would-that-be-possible-to-remove-all-event-handlers에서 꽤 좋은 답변을 가지고 있습니다. 이것이 반성없이 가능하지 않은 이유에 대한 클릭 이벤트 (click-of-the-click-event-of-a). 문제를 다르게 접근해야 할 수도 있습니다. –

+1

달성하고자하는 근본적인 문제는 무엇입니까? – RQDQ

+0

WPF에 WinForms 코드를 적용하려고한다는 것을 알고 있습니까? – Douglas

답변

19

아래 어떤 라우트 된 이벤트에 대한 모든 가입 이벤트 처리기를 검색하기위한 유용한 유틸리티 방법 :

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

위를 사용하여 메소드의 구현은 매우 간단하게 :

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

이것은 닫힌 질문에 불행하게도 붙어있는 매우 유용한 답입니다. . 나는 당신이 동일한 대답을 제공함으로써 "중복"이 향상 될 것이라고 생각합니다. – phloopy

+1

@phloopy : 좋습니다. 방금 위의 솔루션의 [개선 된 버전] (http://stackoverflow.com/a/12618521/1149773)을 게시했습니다. – Douglas

관련 문제