隧道事件:
在视觉树 从上往下,从window->实际源头,一般为被点击的控件。
有preview标注的的都是隧道事件
冒泡事件:
在视觉树,丛下往上,点击的控件,一直到最上层(window)
没有preview标注的的都是冒泡事件
理解事件的触发顺序有助于我们更好的搭建程序结构
举例代码如下:
<Window x:Class="wpfpreview.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:wpfpreview"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Name="grid">
<TextBlock Name="btn" Text="aaa" />
</Grid>
</Window>
这个是xaml,window里面有一个Grid, Grid里面有一个TextBlock
CS代码如下:
namespace wpfpreview
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.PreviewMouseDown += MainWindow_PreviewMouseDown;
grid.PreviewMouseDown += Grid_PreviewMouseDown;
btn.PreviewMouseDown += Btn_PreviewMouseDown;
this.MouseDown += MainWindow_MouseDown;
grid.MouseDown += Grid_MouseDown;
btn.MouseDown += Btn_MouseDown;
}
//执行顺序如下:
private void Btn_MouseDown(object sender, MouseButtonEventArgs e)
{
//4
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
//5
}
private void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
//6
}
private void Btn_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
//3
}
private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
//2
}
private void MainWindow_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
//1
}
}
}
执行顺序就是 方法里面标注的数字
先触发preview事件(隧道事件),再触发 冒泡事件
像一个U型图:
总结:先隧道,后冒泡
若在隧道中任意位置有e.handle=true,那么后面整个链路将不会执行