【问题标题】:How to remove all Click event handlers? [duplicate]如何删除所有 Click 事件处理程序? [复制]
【发布时间】:2012-03-15 03:26:15
【问题描述】:

可能重复: How would that be possible to remove all event handlers of the Click event of a Button?

我想从按钮中删除所有单击事件处理程序。我在 Stack Overflow 问题 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。

【问题讨论】:

  • 我对为什么返回 null 无能为力,但 @JonSkeet 在 stackoverflow.com/questions/6828054/… 上有一个很好的答案,说明为什么不经过反思就不可能做到这一点。也许您需要以不同的方式解决问题。
  • 您要解决的根本问题/您要实现的目标是什么?
  • 您意识到您正在尝试将 WinForms 代码应用于 WPF?
  • 查看答案“动态删除事件处理程序的解决方案(使用反射)。有更好的方法吗?” stackoverflow.com/questions/11031149/…

标签: c# .net wpf event-handling


【解决方案1】:

以下是一个有用的实用方法,用于检索任何路由事件的所有订阅事件处理程序:

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

【讨论】:

  • 这是一个非常有用的答案,不幸的是附在一个封闭的问题上。我认为您也可以在那里提供相同的答案来改进“重复”。
  • @phloopy:好建议。我刚刚在那里发布了上述解决方案的improved version
猜你喜欢
  • 2016-07-05
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 2012-09-04
  • 1970-01-01
相关资源
最近更新 更多