路由事件

  首先就是控件的封装。WPF中,我们可以将一个控件作为另一个控件的子控件,从而呈现丰富的效果。例如我们可以在一个Button中包含一个图像。在这种情况下,对图像的点击实际上应该是对按钮的点击。正因为如此,我们期望真正触发被点击事件的控件是Button,而不是嵌在其中的图像。这正好要求WPF将点击事件沿视觉树依次传递,即路由事件的路由功能。可以说,这是WPF添加路由事件的最直观理由。

  同样由于WPF提供了丰富的组合模型,一小块程序界面组成中就可能包含了多个相同的界面元素。为了能在一处执行对特定事件的侦听,而不是为这些界面组成依次添加事件处理函数。路由事件为这种情况提供了一种较为简单的处理方式:在它们的公共父元素中添加事件处理函数。在该路由事件路由到该元素时,事件处理函数才会被调用。例如在为TreeView中为DragDrop功能提供支持的时候,您不可能在各个条目中依次标明对鼠标操作的响应,而应在TreeView元素中侦听鼠标操作事件。

 

一、自定义路由事件

三个步骤:

(1)   声明并注册路由事件。

(2)为路由事件添加CLR事件包装

(3)创建可以激发路由事件的方法

     public abstract class ButtonBase:ContentControl
    {
//声明并注册路由事件
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase)); //为路由事件添加CLR事件包装 public event RoutedEventHandler Click { add { this.AddHandler(ClickEvent, value); } remove { this.RemoveHandler(ClickEvent, value); } }
//激发路由事件的方法,此方法用户在单击鼠标时会被Windows系统调用
protected virtual void OnClick() { RoutedEventArgs newEvent = new RoutedEventArgs(ButtonBase.ClickEvent, this); this.RaiseEvent(newEvent); } }
EventManager.RegisterRoutedEvent的四个参数
(1)第一个参数string类型,被称为路由事件的名称,与CLR属性包装器的名称一致。
(2)第二个参数为路由事件的策略,路由事件一般使用以下三种路由策略:

1) Bubble冒泡:由事件源向上传递一直到最外层容器(Window或者Page)。

2) 直达接:模仿CLR直接事件,直接将事件消息送达到事件处理器。

3) 隧道:从元素树的根部调用事件处理程序并依次向下深入直到事件源。

一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件。

(3)第三个参数用于指定事件处理器的类型。事件处理器的返回值类型和参数列表必须与此参数指定的委托一致。

(4)第四个参数用于指定路由事件的宿主是哪个类型。

路由事件

上一篇:转载:在Ubuntu系统下装Win7并引导双系统


下一篇:WIN API 擦除所绘图像