我有一个自定义的Button类,在单击它时总是执行相同的操作(打开特定的窗口)。我添加了一个Click事件,该事件可以在按钮的XAML中分配,就像常规按钮一样。
单击它后,如果已分配了Click事件处理程序,则我想执行它,否则,我要执行默认操作。问题在于,显然没有办法检查是否将任何处理程序添加到事件中。
我认为对该事件执行null检查即可:
if (Click == null)
{
DefaultClickAction();
}
else
{
RaiseEvent(new RoutedEventArgs(ClickEvent, this));;
}
...但是无法编译。编译器告诉我,除了+ =或-=之外,我无法对定义类之外的事件进行任何操作,尽管我正在尝试在定义类内部进行此检查。
我已经实现了正确的行为,但是它丑陋且冗长,我无法相信没有内置的方法可以做到这一点。我肯定错过了什么。
以下是相关代码:
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方法直接传递您的路由事件,而这是某人必须做的事情才能将事件挂接到链上。最后,如果有人为该事件注册一个类处理程序,则不会使用CLR事件(在为MyButtonClass的任何实例引发该事件时都将得到通知)。如果查看类似UIElement.BuildRouteHelper的内容,您将看到WPF建立事件路由所经历的所有步骤以及引发事件时将调用的对象。
如果您确实需要知道是否有任何侦听器,那么最好创建仅CLR事件而不是路由事件。然后,您可以检查您的代表是否为空。
关于c# - 检查RoutedEvent是否具有任何处理程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2716066/