WPF中的系统事件一般都是路由事件,陆有事件可以是冒泡也可以是隧道事件,事件在逻辑树中向上或者向下传递。
WPF中许多和用户输入有关的事件一般都是冒泡和隧道事件成对的出现。例如,KeyDown 事件(冒泡)和PreviewKeyDown 事件(隧道)是一对。
当他们成对出现的时候,隧道事件一般会首先被触发,然后是冒泡事件。
例如下图中,Window包含一个StackPanel,StackPanel又再包含了一个StackPanel ,最后的StackPanel中包含一个TextBox。他们都注册了KeyDown 事件(冒泡)和PreviewKeyDown 事件。事件的执行顺序如下:
1. 用户按下键盘,进行输入
2. Window 的PreviewKeyDown事件触发
3. 外部的StackPanel 的PreviewKeyDown事件触发
4. 底部的StackPanel 的PreviewKeyDown事件触发
5. TextBox 的PreviewKeyDown事件触发
6. TextBox 的KeyDown事件触发
7. 底部的StackPanel 的KeyDown事件触发
8. 外部的StackPanel 的KeyDown事件触发
9. Window 的KeyDown事件触发
冒泡和隧道事件成对出现,如果在隧道事件的相应函数中将事件标记为已处理(设置KeyEventArgs.Handled 为 true),那么与之对应的冒泡事件将不会被触发。因为这两个事件公用的是一个KeyEventArgs 实例,所以如果上面的例子中将某个PreviewKeyDown 事件设置为已处理,那么与之对应的KeyDown 事件也会被认为已处理。
原文地址:https://wpf.2000things.com/2012/06/22/586-bubbling-and-tunneling-events-are-typically-paired/
*************************************译者注***************************************
并不是所有的冒泡事件都有对应的隧道事件,它们不一定是一定成对的,比如Button的Click事件。
WPF有三种路由事件方式:冒泡,隧道和直接触发(由事件源直接触发,但不会在可视树中上下传递)。