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

更新:2007 年 11 月

在路由中的任何给定节点上,路由事件可以由类处理程序或实例处理程序来处理。首先调用类处理程序,类实现功能可以使用它们来禁止事件进行实例处理,或者在基类所拥有的事件上引入其他特定于事件的行为。本示例阐释了两个紧密相关的、用来实现类处理程序的技术。

示例

本示例使用一个基于 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);
}

如果基类或者这个特定方法没有虚方法,则可以使用 EventManagerRegisterClassHandler 的实用工具方法直接添加类处理。此方法只应当从正在添加类处理的类的静态初始化内部调用。下面的示例为 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
}

请参见

任务

如何:处理路由事件

概念

将路由事件标记为“已处理”和“类处理”

路由事件概述

参考

EventManager