WPF-11 路由事件之一

什么是路由事件?

我们从两个维度来理解路由事件:

功能的角度来看,路由事件是一种事件类型,不仅仅可以在事件源上处理事件响应,还可以在元素树的多个侦听器上处理事件响应(事件侦听器是附加和调用事件处理程序的元素。事件源是最初引发事件的元素或对象)

实现的角度来看,路由事件是使用 CLR 事件“包装器”实现的,由 RoutedEvent 类的实例支持,并由 WPF 事件系统处理。

根据路由事件的定义方式,当事件在源元素上引发时:

  1. 从源元素到根元素(通常是页面或窗口)通过元素树冒泡

  2. 从根元素到源元素通过元素树向下隧道

  3. 不遍历元素树,只出现在源元素上

<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)要求引用的事件是路由事件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值