WPF—路由事件详解

WPF---路由事件

路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件。路由事件是一个CLR事件。

路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码(如果用传统的方式实现一个操作,执行整个事件的调用则需要执行代码将事件串联起来)。

路由事件的路由策略:

所谓的路由策略就是指:路由事件实现遍历元素的方式。

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

(1) 冒泡:由事件源向上传递一直到根元素。

(2) 直接::直接路由事件与普通的.NET事件是非常相似的,他们都起源于一个元素,并且不能够传递给其它的元素。只有事件源才有机会响应事件。

(3) 隧道:从元素树的根部调用事件处理程序并依次向下深入直到事件源。一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件。

管道

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

管道事件按照惯例,他们的名字中都有一个preview前缀,一般来说管道事件都有他的配对的冒泡事件,例如:PreviewMouseDown和MouseDown就是配对事件,如果同时存在的话,那么就会先执行管道事件然后才执行配对的冒泡事件。当然e.Handled=true,依然能够阻断事件。

当TextBlock的事件触发时,会从根元素进行传递直到TextBlock自身

cs 复制代码
    // XAML标签布局
        <Grid>
            <StackPanel Width="200"
                        Background="Gray"
                        Height="40"
                        PreviewMouseUp="StackPanel_MouseUp">
                <TextBlock Height="40" Background="blue" Width="40" Margin="-150,0,0,0"
                           PreviewMouseUp="TextBlock_MouseUp">
                </TextBlock>
            </StackPanel>
        </Grid>
    
    // 在CS后台文件写对应的数据
        private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Console.WriteLine("子控件textblock 鼠标松开");
        }
    
        private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Console.WriteLine("父控件StackPane 鼠标松开");
        }

结果:

冒泡

由事件源向上传递一直到根元素。

当触发TextBlock的事件时,会从自身一直向上传递直到根元素。

cs 复制代码
    // XAML标签布局
    <Grid>
        <StackPanel Width="200"
                    Background="Gray"
                    Height="40"
                    MouseUp="StackPanel_MouseUp">
            <TextBlock Height="40"
                       Background="blue"
                       Width="40"
                       Margin="-150,0,0,0"
                       MouseUp="TextBlock_MouseUp">
            </TextBlock>
        </StackPanel>
    </Grid>
    
    // 在CS后台文件写对应的数据
    private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e)
    {
        Console.WriteLine("子控件textblock 鼠标松开");
    }
    
    private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e)
    {
        Console.WriteLine("父控件StackPane 鼠标松开");
    }

结果:

直接

直接路由事件只传递一层。它源自一个元素,并且不传递给其他元素,MouseEnter事件(当鼠标指针移动到元素上时发生)是直接路由事件。

当鼠标移到TextBlock的时候会响应BlockMouseEnter事件,但是不会响应StackMouseEnter事件

cs 复制代码
    <StackPanel Orientation="Vertical" MouseEnter="StackMouseEnter" Background="Yellow">
      <TextBlock Text="Block鼠标移进来" Background="AliceBlue" Height="50" Width="100" MouseEnter="BlockMouseEnter" />
    </StackPanel>

如何阻断事件

e.Handled = true; 阻断事件

当Handled属性为true时阻断该事件的传递,后续事件不会再进行执行

cs 复制代码
    // XAML标签布局
        <Grid>
            <StackPanel Width="200"
                        Background="Gray"
                        Height="40"
                        PreviewMouseUp="StackPanel_MouseUp">
                <TextBlock Height="40" Background="blue" Width="40" Margin="-150,0,0,0"
                           PreviewMouseUp="TextBlock_MouseUp">
                </TextBlock>
            </StackPanel>
        </Grid>
    
    // 在CS后台文件写对应的数据
        private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Console.WriteLine("子控件textblock 鼠标松开");
        }
    
        private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Console.WriteLine("父控件StackPane 鼠标松开");
            e.Handled = true;// 阻断事件
        }

结果:

相关推荐
Aomnitrix11 分钟前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
大飞pkz13 分钟前
【设计模式】C#反射实现抽象工厂模式
设计模式·c#·抽象工厂模式·c#反射·c#反射实现抽象工厂模式
程序消消乐15 分钟前
Kafka 入门指南:从 0 到 1 构建你的 Kafka 知识基础入门体系
分布式·kafka
智能化咨询16 分钟前
Kafka架构:构建高吞吐量分布式消息系统的艺术——进阶优化与行业实践
分布式·架构·kafka
Chasing__Dreams16 分钟前
kafka--基础知识点--5.2--最多一次、至少一次、精确一次
分布式·kafka
唐青枫2 小时前
从入门到进阶:C#.NET Stopwatch 计时与性能测量全攻略
c#·.net
在未来等你7 小时前
Elasticsearch面试精讲 Day 17:查询性能调优实践
大数据·分布式·elasticsearch·搜索引擎·面试
大数据CLUB10 小时前
基于spark的澳洲光伏发电站选址预测
大数据·hadoop·分布式·数据分析·spark·数据开发
未来之窗软件服务11 小时前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
1uther12 小时前
Unity核心概念⑨:Screen
开发语言·游戏·unity·c#·游戏引擎