理解WPF路由事件

(一)什么时路由事件
功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。
实现定义:路由事件是一个 CLR 事件,可以由 RoutedEvent 类的实例提供支持并由 Windows Presentation Foundation (WPF) 事件系统来处理
(二)路由事件的划分
(1)冒泡:针对事件源调用事件处理程序。路由事件随后会路由到后续的父元素,直到到达元素树的根。
(2)隧道:最初将在元素树的根处调用事件处理程序。随后,路由事件将朝着路由事件的源节点元素(即引发路由事件的元素)方向,沿路由线路传播到后续的子元素。
(3)直接:只有源元素本身才有机会调用处理程序以进行响应。这与 Windows Forms用于事件的“路由”相似。但是,与标准 CLR 事件不同的是,直接路由事件支持类处理而且可以由 EventSetter 和 EventTrigger 使用。
(三)e.Handled=true“已处理”
如果将 Handled 设置为 true,以此将事件标记为“已处理”,则将“停止”隧道路由或冒泡路由,同时,类处理程序在某个路由点处理的所有事件的路由也将“停止”。
(四)下面列子事件执行循序(操作都是点击TextBlock)
(1)当为冒泡事件时:TextBlock-->Grid-->Window
(2)当为隧道事件时:Window-->Grid-->TextBlock
关于e.Handled=true在列子中的应用理解:e.Handled==true放在哪个事件中执行后,哪个事件之后的路由事件不在执行。

(五)代码

(1)UI代码

1 <Window x:Class="WpfEvent.MainWindow"
2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4         Title="MainWindow" Height="350" Width="525" x:Name="window" >
5     <Grid Width="300" Height="200" x:Name="grid"  Background="Red">
6         <TextBlock x:Name="tbx" Width="100" Height="27" Background="Blue" />
7     </Grid>
8 </Window>

(2)后台代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows;
 6 using System.Windows.Controls;
 7 using System.Windows.Data;
 8 using System.Windows.Documents;
 9 using System.Windows.Input;
10 using System.Windows.Media;
11 using System.Windows.Media.Imaging;
12 using System.Windows.Navigation;
13 using System.Windows.Shapes;
14
15 namespace WpfEvent
16 {
17     //(一)什么时路由事件
18     //功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。
19     //实现定义:路由事件是一个 CLR 事件,可以由 RoutedEvent 类的实例提供支持并由 Windows Presentation Foundation (WPF) 事件系统来处理
20     //(二)路由事件的划分
21     //(1)冒泡:针对事件源调用事件处理程序。路由事件随后会路由到后续的父元素,直到到达元素树的根。
22     //(2)隧道:最初将在元素树的根处调用事件处理程序。随后,路由事件将朝着路由事件的源节点元素(即引发路由事件的元素)方向,沿路由线路传播到后续的子元素。
23     //(3)直接:只有源元素本身才有机会调用处理程序以进行响应。这与 Windows Forms用于事件的“路由”相似。但是,与标准 CLR 事件不同的是,直接路由事件支持类处理而且可以由 EventSetter 和 EventTrigger 使用。
24     //(三)e.Handled=true“已处理”
25     //如果将 Handled 设置为 true,以此将事件标记为“已处理”,则将“停止”隧道路由或冒泡路由,同时,类处理程序在某个路由点处理的所有事件的路由也将“停止”。
26     //(四)下面列子事件执行循序(操作都是点击TextBlock)
27     //(1)当为冒泡事件时:TextBlock-->Grid-->Window
28     //(2)当为隧道事件时:Window-->Grid-->TextBlock
29     //关于e.Handled=true在列子中的应用理解:e.Handled==true放在哪个事件中执行后,哪个事件之后的路由事件不在执行。
30     /// <summary>
31     /// MainWindow.xaml 的交互逻辑
32     /// </summary>
33     public partial class MainWindow : Window
34     {
35         public MainWindow()
36         {
37             InitializeComponent();
38             this.grid.MouseLeftButtonDown += new MouseButtonEventHandler(grid_MouseLeftButtonDown);
39             this.tbx.MouseLeftButtonDown += new MouseButtonEventHandler(tbx_MouseLeftButtonDown);
40             this.MouseLeftButtonDown += new MouseButtonEventHandler(window_MouseLeftButtonDown);
41
42             //this.grid.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(grid_PreviewMouseLeftButtonDown);
43             //this.tbx.PreviewMouseLeftButtonDown+=new MouseButtonEventHandler(tbx_PreviewMouseLeftButtonDown);
44             //this.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(window_PreviewMouseLeftButtonDown);
45
46         }
47
48
49
50         private void grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
51         {
52             MessageBox.Show("我是Grid");
53         }
54
55         private void window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
56         {
57             MessageBox.Show("我是窗体");
58
59         }
60
61         private void tbx_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
62         {
63             MessageBox.Show("我是TextBlock");
64             e.Handled = true;
65
66         }
67
68
69
70         private void window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
71         {
72             MessageBox.Show("我是窗体");
73
74
75         }
76
77         private void grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
78         {
79             MessageBox.Show("我是Grid");
80             //e.Handled = true;
81
82         }
83
84         private void tbx_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
85         {
86             MessageBox.Show("我是TextBlock");
87
88         }
89
90     }
91 }
时间: 2024-08-30 08:16:43

理解WPF路由事件的相关文章

WPF路由事件二:路由事件的三种策略

一.什么是路由事件 路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件.路由事件是一个CLR事件. 路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码(如果用传统的方式实现一个操作,执行整个事件的调用则需要执行代码将事件串联起来). 路由事件的路由策略: 所谓的路由策略就是指:路由事件实现遍历元素的方式. 路由事件一般使用以下三

[总结]使用WPF路由事件过程中遇到的一些小问题

写在前面 本文一开始会给出一个使用WPF路由事件的实例,因为本文所有的表述都将基于该实例.而本文所给实例来自于<WPF自定义路由事件>一文,在<WPF自定义路由事件>一文中会对实例代码做详细说明,所以,大家在阅读本文实例代码期间若存在疑问,可以先去看看<WPF自定义路由事件>一文,看是否能从中获得你想要的解答. 本文实例 1 新建DetailReportEventArgs类,该类派生自RoutedEventArgs类,RoutedEventArgs类包含与路由事件相关的

WPF路由事件学习转(二)

在传统的.net中已经有了事件机制了,为什么在WPF中要加入路由事件来取代事件呢,最直观的原因就是典型的WPF应用程序使用很多元素关联和组合起来,从而有了两个概念,LogicalTree 和 VisualTree,那么它们分别是什么呢,举个例子: 这就是LogicalTree,一个Grid里面镶嵌了其他控件或布局组件,这相当于一棵树中的叶子.而VisualTree呢?它就是一个树中的叶子里面的结构,用放大镜看一下,其实叶子里面的结构也是一颗树结构,这就是VisualTree了,例如 好了,既然W

WPF 路由事件

每每谈到WPF的路由事件,我总是比较模糊的,因为我一般很少用,因为一般是用Binding来满足数据驱动界面的要求,要么就是通过路由命令来执行我想要做的方法,路由事件确实用得少,那么路由事件跟一般的事件的区别在哪里呢?如何使用呢?下面讲揭开其神秘的面纱: 首先说一说事件的历史,在windows操作系统上运行程序,都是消息驱动的,早期Windows API开发和MFC开发的时候可以直接看到各种消息,并且定义消息,到了VB和COM的时代,消息被封装成了事件,到了.NET时代也是事件,但是是直接式的,但

WPF路由事件一:逻辑树和可视树

一.什么是逻辑树 逻辑树就是描述WPF界面元素的实际构成,它是由程序在XAML中所有的UI元素组成.最显著的特点就是由布局控件.或者其他常用的控件组成. 1 <Window x:Class="WpfRouteEvent.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.c

WPF路由事件:逻辑树和可视树

一.什么是逻辑树 逻辑树就是描述WPF界面元素的实际构成,它是由程序在XAML中所有的UI元素组成.最显著的特点就是由布局控件.或者其他常用的控件组成. 1 <Window x:Class="WpfRouteEvent.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.c

WPF自定义路由事件

一 概要 本文通过实例演示WPF自定义路由事件的使用,进而探讨了路由事件与普通的CLR事件的区别(注:"普通的CLR事件"这个说法可能不太专业,但是,我暂时也找不到什么更好的称呼,就这么着吧,呵呵.)(扩展阅读:例说.NET事件的使用). 二 实例演示与说明 1 新建DetailReportEventArgs类,该类派生自RoutedEventArgs类,RoutedEventArgs类包含与路由事件相关的状态信息和事件数据.DetailReportEventArgs类中定义了属性Ev

WPF自定义路由事件(二)

WPF中的路由事件 as U know,和以前Windows消息事件区别不再多讲,这篇博文中,将首先回顾下WPF内置的路由事件的用法,然后在此基础上自定义一个路由事件. 1.WPF内置路由事件 WPF中的大多数事件都是路由事件,WPF有3中路由策略: 具体不多讲,单需要注意的是WPF路由事件是沿着VIsualTree传递的.VisualTree与LogicalTree的区别在于:LogicalTree的叶子节点是构成用户界面的控件(xaml紧密相关),而VisualTree要连控件中的细微结构也

WPF的路由事件、冒泡事件、隧道事件(预览事件)

原文:WPF的路由事件.冒泡事件.隧道事件(预览事件) 本文摘要: 1:什么是路由事件: 2:中断事件路由: 3:自定义路由事件: 4:为什么需要自定义路由事件: 5:什么是冒泡事件和预览事件(隧道事件): 1:什么是路由事件 WPF中的事件为路由事件,所谓路由事件,MSDN定义如下: 功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件. 实现定义:路由事件是一个 CLR 事件,可以由 RoutedEvent 类的实例提供支持并由 Window