c# - 如何删除 'Click' 的 'Button' 事件的所有事件处理程序?

标签 c# .net events event-handling

我有一个按钮控件,我需要删除所有附加到其 Click event 的事件处理程序.

这怎么可能?

Button button = GetButton();
button.Click.RemoveAllEventHandlers();

最佳答案

Note: Since the question on which I posted my original answer was closed as a duplicate of this question, I'm cross-posting an improved version of my answer here. This answer only applies to WPF. It will not work on Windows Forms or any other UI framework.

下面是一个有用的实用方法,用于删除订阅给定元素上的路由事件的所有事件处理程序。如果愿意,您可以简单地将其转换为扩展方法。

/// <summary>
/// Removes all event handlers subscribed to the specified routed event from the specified element.
/// </summary>
/// <param name="element">The UI element on which the routed event is defined.</param>
/// <param name="routedEvent">The routed event for which to remove the event handlers.</param>
public static void RemoveRoutedEventHandlers(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);

    // If no event handlers are subscribed, eventHandlersStore will be null.
    // Credit: https://stackoverflow.com/a/16392387/1149773
    if (eventHandlersStore == null)
        return;

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

    // Iteratively remove all routed event handlers from the element.
    foreach (var routedEventHandler in routedEventHandlers)
        element.RemoveHandler(routedEvent, routedEventHandler.Handler);
}

然后您可以轻松地为按钮的 Click 事件调用此实用程序方法:

RemoveRoutedEventHandlers(button, Button.ClickEvent);

编辑:我复制了bug fix implemented by corona ,这会在没有订阅任何事件处理程序时阻止该方法抛出 NullReferenceException。信用(和赞成票)应该归功于他们的回答。

关于c# - 如何删除 'Click' 的 'Button' 事件的所有事件处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6828054/

相关文章:

c# - 如何从 MVC 中的父 Controller 返回 View

c# - 在当前使用访问者模式的 C# (2.0) 中使用委托(delegate)来简化类型安全的抽象语法树

events - 冒泡的概念是什么?

Javascript onscroll 事件未被调用

java - SWT 中的 'show' 和 'paint' 事件有什么区别?

c# - MultiBinding 转换器未绑定(bind)到 DataTemplate 中的 TextBlock

c# - 使用面板 RenderControl 方法时无法找到具有 id 的控件

c# - 是否有一些正确的方法可以为 IEnumerable 模型字段添加模型错误以突出显示 View 中的特定输入但不是全部?

c# - 从 Task.Run 中抛出异常显示 "Not Handled from User Code"消息

.net - Awesomium WebControl 挂起