WPF-11 路由事件之一

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)要求引用的事件是路由事件。

以上是关于WPF-11 路由事件之一的主要内容,如果未能解决你的问题,请参考以下文章

NC5 二叉树根节点到叶子节点的所有路径和

如何监视 WPF 中的所有窗口,在所有窗口中订阅事件或者附加 UI

Kafka事件路由器:过滤和基于内容的路由,如何?

WPF事件内置路由事件

将触摸事件传递给多个选项之一

牛客题霸 NC5 二叉树根节点到叶子节点的所有路径和