WPF路由事件(通过EventManager.RegisterClassHandler)

5

我正在尝试寻找一种通用的方式来追踪当前窗口中任何控件(无论是否数据绑定)的“修改”事件(例如,启用或禁用典型选项窗口中的应用按钮)。实际上,我只需要连接几个事件处理程序,如ComboBox.SelectionChanged或TextBox.TextChanged。在WinForms中,我不得不遍历窗体中的所有控件,并逐个连接这些事件处理程序,它也能正常工作。在WPF中,我认为可以用更少的代码完成它,如下所示:

EventManager.RegisterClassHandler( typeof(MyCtrl)
                                 , ComboBox.SelectionChangedEvent
                                 , new RoutedEventHandler(OnChanged));

使用这一行代码,我可以为MyCtrl中的所有组合框连接选择更改事件。然而,我遇到的问题是,如果我理解得正确,当窗口中还有另一个不是组合框但也派生自“Selector”的控件时,此事件也会被触发。例如,我在同一窗口上还有一个数据网格(实际上没有组合框列),当我选择不同的行时,此事件也会被触发。
因此,似乎上述代码行钩住了所有派生自Selector基类的控件的SelectionChanged事件,而不仅仅是组合框。
这是正确的吗?如何只钩住所有组合框的SelectionChanged事件?
编辑并附带更多示例:在同一个控件上,我有一个组合框和一个按钮,我想按以下方式跟踪Button.Click和ComboBox.SelectionChanged事件
EventManager.RegisterClassHandler( typeof(MyCtrl)
                                 , ComboBox.SelectionChangedEvent
                                 , new RoutedEventHandler(OnChanged));
EventManager.RegisterClassHandler( typeof(MyCtrl)
                                 , Button.ClickEvent
                                 , new RoutedEventHandler(OnChanged));

问题在于,当我点击ComboBox下拉按钮后,就立即收到了Button.Click事件。我该如何防止这种情况发生?
以下是有关此事件的一些额外信息:
?e.OriginalSource
{System.Windows.Controls.Primitives.ToggleButton Content: 
            IsChecked:True}
    base {System.Windows.Controls.Primitives.ButtonBase}: 
            {System.Windows.Controls.Primitives.ToggleButton Content: IsChecked:True}
    IsChecked: true
    IsThreeState: false
?e.RoutedEvent
{ButtonBase.Click}
    HandlerType: {Name = "RoutedEventHandler" 
                  FullName = "System.Windows.RoutedEventHandler"}
    Name: "Click"
    OwnerType: {Name = "ButtonBase" 
                FullName = "System.Windows.Controls.Primitives.ButtonBase"}
    RoutingStrategy: Bubble
1个回答

2
我认为你无法阻止这种情况发生,因为那些控件会重用同样的事件,通常这是一件好事。你可以尝试根据发送者进行过滤,并忽略来自你不感兴趣的控件的调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接