检查RoutedEvent是否有任何处理程序

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

单击它时,我想执行Click事件处理程序(如果已分配),否则我想执行默认操作。 问题是,显然没有办法检查是否有任何处理程序添加到事件中。

我认为对事件的空检查会这样做:

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

……但那不会编译。 编译器告诉我除了+ =或 – =之外我不能对定义类之外的事件执行任何操作,尽管我正在尝试执行此操作检查INSIDE定义类。

我自己实现了正确的行为,但是它很丑陋且冗长,我无法相信没有内置的方法来做到这一点。 我肯定错过了什么。

这是相关的代码:

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

不,这是不可能的。 实际上你所拥有的代码假定他们正在控制你自己的事件,但是你宣布一个Bubble事件而不是一个Direct事件,所以从技术上讲,某些事情可以在元素链的更上方听取事件。 此外,从技术上讲,不需要使用CLR事件来挂钩事件; 一个人可以直接使用AddHandler方法传递你的路由事件,这就是有人必须做的事情来将事件挂钩到链上。 最后,如果有人为事件注册了一个类处理程序(在为MyButtonClass的任何实例引发该事件时要通知),则不会使用CLR事件。 如果您查看UIElement.BuildRouteHelper之类的内容,您将看到WPF完成所有步骤以建立事件路由以及在引发事件时将调用的对象。

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