理解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 }

 

理解WPF路由事件

上一篇:php如何判断当前的操作系统是linux还是windows


下一篇:c# GDI画图 双缓存画图分析