WPF-11 路由事件之一
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF-11 路由事件之一相关的知识,希望对你有一定的参考价值。
什么是路由事件?
我们从两个维度来理解路由事件:
功能的角度来看,路由事件是一种事件类型,不仅仅可以在事件源上处理事件响应,还可以在元素树的多个侦听器上处理事件响应(事件侦听器是附加和调用事件处理程序的元素。事件源是最初引发事件的元素或对象)
实现的角度来看,路由事件是使用 CLR 事件“包装器”实现的,由 RoutedEvent 类的实例支持,并由 WPF 事件系统处理。
根据路由事件的定义方式,当事件在源元素上引发时:
从源元素到根元素(通常是页面或窗口)通过元素树冒泡
从根元素到源元素通过元素树向下隧道
不遍历元素树,只出现在源元素上
<Border Height="30" Width="200" BorderBrush="Gray" BorderThickness="1">
<StackPanel Background="LightBlue" Orientation="Horizontal"
Button.Click="StackPanel_Click">
<Button Name="YesButton">YES</Button>
<Button Name="NoButton">No</Button>
<Button Name="CancelButton">Cancel</Button>
</StackPanel>
</Border>
示例中的这三个Button都有自己Click事件,当触发一个button的Click事件时,Button元素的Click事件沿着树传播到根节点,Button和Border没有响应时间处理程序,但是StackPanel会响应。在这个例子中事件传播:Button -> StackPanel -> Border -> 父元素
如何实现路由事件?
我们可以通过WPF框架提供的接口来注册路由事件,由 RoutedEvent 类的实例支持。从注册中获得的 RoutedEvent 实例通常存储为注册它的类的公共静态只读成员。该类称为事件“所有者”类。通常,路由事件是对同名 CLR 事件的“包装器”。CLR 事件包装器包含添加和删除访问器,以便通过特定于语言的事件语法在 XAML 和代码隐藏中附加处理程序。add 和 remove 访问器覆盖其 CLR 实现并调用路由事件 AddHandler 和 RemoveHandler 方法。路由事件机制类似于依赖属性的机制。
以下示例注册 Tap 路由事件,存储返回的 RoutedEvent 实例,并实现 CLR 事件包装器。
// Register a custom routed event using the Bubble routing strategy.
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
name: "Tap",
routingStrategy: RoutingStrategy.Bubble,
handlerType: typeof(RoutedEventHandler),
ownerType: typeof(CustomButton));
// Provide CLR accessors for adding and removing an event handler.
public event RoutedEventHandler Tap
add AddHandler(TapEvent, value);
remove RemoveHandler(TapEvent, value);
路由策略
路由事件使用以下三种路由策略之一:
冒泡:最初,事件源上的事件处理程序被调用。路由事件然后路由到连续的父元素,依次调用它们的事件处理程序,直到它到达元素树根。大多数路由事件使用冒泡路由策略。冒泡路由事件通常用于报告来自复合控件或其他 UI 元素的输入或状态更改。
隧道:最初,调用元素树根处的事件处理程序。路由事件然后路由到连续的子元素,依次调用它们的事件处理程序,直到它到达事件源。遵循隧道路由的事件也称为预览事件。WPF 输入事件通常实现为预览和冒泡对。
直接:仅调用事件源上的事件处理程序。这种非路由策略类似于标准 CLR 事件的 Windows 窗体 UI 框架事件。与 CLR 事件不同,直接路由事件支持类处理并且可由 EventSetters 和 EventTriggers 使用。
为什么用路由事件?
软件开发人员并需要知道你正在处理的事件是路由事件,路由事件本身具有自己的特性,如果你正在处理元素自身引发的事件,则该行为是不可用的。但是,如果你将事件附加到父元素或者子元素 ,这时路由事件就体现了它自己的特性。
路由事件支持沿事件路由的元素之间的事件信息交换,因为每个侦听器都可以访问相同的事件数据实例。如果一个元素更改了事件数据中的某些内容,则该更改对事件路由中的后续元素可见。 WPF 样式和模板功能(例如 EventSetters 和 EventTriggers)要求引用的事件是路由事件。
以上是关于WPF-11 路由事件之一的主要内容,如果未能解决你的问题,请参考以下文章