如何:为路由事件添加类处理

路由事件可以由路由中任何给定节点上的类处理程序或实例处理程序处理。 类处理程序首先被调用,并且可以由类实现用于抑制实例处理中的事件,或在基类拥有的事件上引入其他特定于事件的行为。 此示例说明了用于实现类处理程序的两种密切相关的技术。

示例

此示例使用基于 Canvas 面板的自定义类。 应用程序的基本前提是,自定义类在其子元素上引入行为,包括在调用子元素类或其上的任何实例处理程序之前拦截任何鼠标左键单击操作并将其标记为“已处理”。

UIElement 类公开了一个虚拟方法,该方法通过简单地重写事件来启用对 PreviewMouseLeftButtonDown 事件的类处理。 如果这样的虚拟方法在你的类层次结构中的某处可用,则这是实现类处理的最简单方法。 以下代码显示了派生自 Canvas 的“MyEditContainer”中的 OnPreviewMouseLeftButtonDown 实现。 该实现将事件标记为在参数中已处理,然后添加一些代码,以便为源元素提供基本的可见更改。

protected override void OnPreviewMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
    e.Handled = true; //suppress the click event and other leftmousebuttondown responders
    MyEditContainer ec = (MyEditContainer)e.Source;
    if (ec.EditState)
    { ec.EditState = false; }
    else
    { ec.EditState = true; }
    base.OnPreviewMouseRightButtonDown(e);
}
Protected Overrides Sub OnPreviewMouseRightButtonDown(ByVal e As System.Windows.Input.MouseButtonEventArgs)
    e.Handled = True 'suppress the click event and other leftmousebuttondown responders
    Dim ec As MyEditContainer = CType(e.Source, MyEditContainer)
    If ec.EditState Then
        ec.EditState = False
    Else
        ec.EditState = True
    End If
    MyBase.OnPreviewMouseRightButtonDown(e)
End Sub

如果基类或该特定方法上没有可用的虚拟方法,则可以使用 EventManager 类的实用方法 RegisterClassHandler 直接添加类处理。 只能在要添加类处理的类的静态初始化中调用此方法。 此示例为 PreviewMouseLeftButtonDown 添加了另一个处理程序,在这种情况下,注册的类是自定义类。 相反,当使用虚拟方法时,注册的类实际上是 UIElement 基类。 在基类和子类各自注册类处理的情况下,将首先调用子类处理程序。 应用程序中的行为是,首先此处理程序将显示其消息框,然后将显示虚拟方法处理程序中的视觉更改。

static MyEditContainer()
{
  EventManager.RegisterClassHandler(typeof(MyEditContainer), PreviewMouseRightButtonDownEvent, new RoutedEventHandler(LocalOnMouseRightButtonDown));
}
internal static void LocalOnMouseRightButtonDown(object sender, RoutedEventArgs e)
{
  MessageBox.Show("this is invoked before the On* class handler on UIElement");
  //e.Handled = true; //uncommenting this would cause ONLY the subclass' class handler to respond
}
Shared Sub New()
    EventManager.RegisterClassHandler(GetType(MyEditContainer), PreviewMouseRightButtonDownEvent, New RoutedEventHandler(AddressOf LocalOnMouseRightButtonDown))
End Sub
Friend Shared Sub LocalOnMouseRightButtonDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
    MessageBox.Show("this is invoked before the On* class handler on UIElement")
    'e.Handled = True //uncommenting this would cause ONLY the subclass' class handler to respond
End Sub

另请参阅