在路由中的任何给定节点上,路由事件可以由类处理程序或实例处理程序来处理。 首先调用类处理程序,类实现功能可以使用它们来禁止事件进行实例处理,或者在基类所拥有的事件上引入其他特定于事件的行为。 本示例阐释了两个紧密相关的、用来实现类处理程序的技术。
示例
本示例使用一个基于 Canvas 面板的自定义类。 应用程序的基本前提就是,在调用子元素类或其上的任何实例处理程序之前,自定义类在其子元素上引入行为(包括解释任何鼠标左键单击并将它们标记为“已处理”)。
UIElement 类公开了一个虚方法,使用该虚方法,只需通过重写 PreviewMouseLeftButtonDown 事件即可对该事件进行类处理。 当这样的虚方法可以在类层次结构的某处使用时,这是实现类处理的最简单方法。 下面的代码演示如何在从 Canvas 派生的“MyEditContainer”中实现 OnPreviewMouseLeftButtonDown。 该实现在参数中将事件标记为“已处理”,然后添加一些代码,以便为源元素提供一个基本的可见变化。
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
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);
}
如果基类或者这个特定方法没有虚方法,则可以使用 EventManager 类 RegisterClassHandler 的实用工具方法直接添加类处理。 此方法只应当从正在添加类处理的类的静态初始化内部调用。 下面的示例为 PreviewMouseLeftButtonDown 添加另一个处理程序,在这种情况下,注册类就是自定义类。 反过来,在使用虚方法时,注册类实际上是 UIElement 基类。 如果基类和子类均注册了类处理功能,则将首先调用子类的处理程序。 应用程序中的行为将是该处理程序首先显示其消息框,随后将显示虚方法处理程序中的可视变化。
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
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
}