检查RoutedEvent是否有任何处理程序 [英] Checking if a RoutedEvent has any handlers

查看:109
本文介绍了检查RoutedEvent是否有任何处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的Button类,它总是执行相同的动作,当它被点击(打开一个特定的窗口)。我添加了一个Click事件,可以在按钮的XAML中分配,就像一个常规的按钮。

I've got a custom Button class, that always performs the same action when it gets clicked (opening a specific window). I'm adding a Click event that can be assigned in the button's XAML, like a regular button.

当它被点击时,我想执行Click事件处理程序if一个已分配,否则我想执行默认操作。问题是,显然没有办法检查是否有任何处理程序被添加到一个事件。

When it gets clicked, I want to execute the Click event handler if one has been assigned, otherwise I want to execute the default action. The problem is that there's apparently no way to check if any handlers have been added to an event.

我认为事件的空检查会做到:

I thought a null check on the event would do it:

if (Click == null) 
{ 
    DefaultClickAction(); 
} 
else 
{ 
    RaiseEvent(new RoutedEventArgs(ClickEvent, this));;
}

...但这不会编译。编译器告诉我,除了+ =或 - =之外,我不能对定义类外的事件做任何事情,但是我试图在定义类中执行这个检查。

...but that doesn't compile. The compiler tells me that I can't do anything other than += or -= to an event outside of the defining class, event though I'm trying to do this check INSIDE the defining class.

我自己实现了正确的行为,但它是丑陋和冗长,我不能相信没有一个内置的方法来做到这一点。

I've implemented the correct behavior myself, but it's ugly and verbose and I can't believe there isn't a built-in way to do this. I must be missing something.

以下是相关代码:

public class MyButtonClass : Control
{
    //...

    public static readonly RoutedEvent ClickEvent =
        EventManager.RegisterRoutedEvent("Click",
                                         RoutingStrategy.Bubble,
                                         typeof(RoutedEventHandler),
                                         typeof(MyButtonClass));

    public event RoutedEventHandler Click
    {
        add { ClickHandlerCount++; AddHandler(ClickEvent, value); }
        remove { ClickHandlerCount--; RemoveHandler(ClickEvent, value); }
    }

    private int ClickHandlerCount = 0;

    private Boolean ClickHandlerExists
    {
        get { return ClickHandlerCount > 0; }
    }

    //...
}


推荐答案

不可能。实际上,你假设他们正在处理你的控件本身的事件,但你正在声明一个泡泡事件而不是直接事件,因此技术上可以听到事件进一步向上元件链。另外,技术上不需要使用CLR事件来挂钩事件;可以只使用AddHandler方法直接传递你的路由事件,这是什么人必须做的事情挂钩事件进一步向上链。最后,如果有人为事件注册了一个类处理程序(要在任何MyButtonClass的任何实例引发事件时通知),CLR事件将不会被使用。如果你看看UIElement.BuildRouteHelper,你会看到WPF经历的所有步骤,以建立事件路由和当事件被调用时将被调用的对象。

No it is not possible. Actually the code you have assumes that they are handling the event on your control itself but you are declaring a Bubble event not a Direct event so technically something can be listening to the event further up the element chain. Also, technically one doesn't need to use the CLR event to hook the event; one can just use the AddHandler method directly passing in your routed event and that is what someone would have to do to hook the event further up the chain. Lastly the CLR event won't be used if someone registers a class handler for the event (to be notified whenever that event is raised for any instance of your MyButtonClass). If you look at something like the UIElement.BuildRouteHelper you will see all the steps that WPF goes through to establish the event route and the objects that will be invoked when the event is raised.

如果你真的需要知道是否有任何监听器,那么你最好创建一个仅CLR事件,而不是一个路由事件。然后,您可以检查您的委托是否为非空。

If you really need to know if there are any listeners then you are better off creating a CLR only event and not a routed event. Then you can check if your delegate is non-null.

这篇关于检查RoutedEvent是否有任何处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆