WPF事件

普通CLR事件

事件的拥有者:即消息的发送者。事件的宿主可以在某些条件下激发它拥有的事件,事件被触发则消息被发送。

事件的响应者:即消息的接收者、处理者。事件接收者使用其事件处理器(EventHandler)对事件做出响应。

事件的订阅关系:事件的拥有者可以随时激发事件。

普通的CLR事件通过事件订阅将事件的发布者与事件的订阅者紧密联系在一起,事件被触发时,事件发布者通过事件订阅将事件消息直接发送给事件订阅者,事件订阅者使用事件处理方法对事件的发生进行响应;

路由事件

路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件,也就是说,触发事件源的父级或子级如果都有对该事件的监听,则都能触发事件。

路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码。

逻辑树和可视树

逻辑树:WPF界面元素的实际构成,它是由程序在XAML中所有的UI元素组成。最显著的特点就是由布局控件、或者其他常用的控件组成。

可视化树:可以说可视树是逻辑树的拓展,就是在界面上能够看见的,布局、控件的内部构成情况。

简单看个例子:

xaml代码:



逻辑树:


可视树:


路由事件使用以下三种路由策略

冒泡:调用事件源上的事件处理程序。然后,路由事件路由到连续的父元素,直到到达元素树的根。大多数路由事件都使用冒泡路由策略。

直接:只有源元素本身才有机会调用处理程序作为响应。

隧道:最初,将调用元素树根目录处的事件处理程序。然后,路由事件沿着路径沿连续的子元素行进,到达作为路由事件源的节点元素(引发路由事件的元素),通常隧道事件也称为"preview"事件。

冒泡跟隧道的路由策略,通常如果在开发的时候不让其继续沿着可视树和逻辑树再向上/向下传递时候,可以将其截断,设置handle=true,这样就会停止传递事件,终止在这个控件中。

自定义路由事件    

创建自定义路由事件大体可以分为三个步骤:

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

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

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


首先是新建了一个类,该类派生自RoutedEventArgs类,RoutedEventArgs类包含与路由事件相关的状态信息和事件数据,再新建了两个属性。


注册定义路由事件通过RoutedEvent RegisterRoutedEvent注册声明。

第一个参数是为注册路由事件的名称,这个名称不可以为空或者空字符串。

第二个参数是代表路由事件的策略,冒泡/隧道/直达之一。

第三个参数与第四个参数的类型均为Type。其中:第三个参数指定事件处理器的类型,第四个参数指定路由事件的宿主类型。本例中的事件处理器类型为EventHandler,所以第三个传入参数为typeof(EventHandler)。路由事件的宿主为DetailReportButton 类,所以第四个传入参数为typeof(DetailReportButton)。


通过add和remove去订阅事件和取消事件,就类似与"+="和"-="。


路由事件的触发在OnClick方法中完成,方法中先实例化DetailReportEventArgs 类,得到对象args,并为args的EventPublisher与EventTime属性赋值,这样就创建了携带有路由事件相关信息的对象。然后调用 RaiseEvent方法把事件消息发送出去。

你可能感兴趣的:(WPF事件)