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

单击时,如果分配了单击事件处理程序,我想执行单击事件处理程序,否则我想执行默认操作。问题在于,显然无法检查是否已将任何处理程序添加到活动中。

我认为该事件的无效检查可以做到:

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

    //...
}
有帮助吗?

解决方案

不,这是不可能的。实际上,您假设他们在控制您的控制本身上处理事件的代码,但您正在宣布 气泡 事件不是 直接的 事件因此,从技术上讲,可以在元素链上进一步聆听该事件。另外,从技术上讲,人们不需要使用CLR事件来连接事件。人们可以直接在路由事件中直接使用Addhandler方法,这就是某人将要在链条上进一步将事件挂钩的要做的事情。最后,如果有人注册了该事件的课程处理程序(每当为MyButtonClass的任何实例提出该事件时,就不会使用CLR事件。如果您查看类似uielement.buildroutehelper之类的东西,您将看到WPF通过建立事件路线的所有步骤以及在升级事件时将被调用的对象。

如果您真的需要知道是否有听众,那么最好只创建仅CLR事件而不是路由事件。然后,您可以检查您的委托是否为非无效。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top