2012-02-24 16 views
7

可能性の重複: How would that be possible to remove all event handlers of the Click event of a Button?すべてのClickイベントハンドラを削除するには?

私はボタンからすべてのクリックイベントハンドラを削除します。スタックオーバーフローの質問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]); 
} 

しかし、この行は常にnullを返します:

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

をそして、この方法は、2006年

に書かれたこの方法のいずれかの最新バージョンはありますか?

注:私はWPF.NET 4.0で作業しています。

+0

私ができますなぜそれがnullを返すのかを大いに助けますが、@ JonSkeetはかなり良い答えをhttp://stackoverflow.com/questions/6828054/how-would-that-be-possible-to-remove-all-event-handlersに持っていますそれが反射なしでは不可能である理由についてのクリックイベント - of-a-of-the-click。おそらく、あなたは問題に異なってアプローチする必要があります。 –

+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

関連する問題