哪些实际场景需要使用Tunneling of events?
我知道对此的一个模糊答案可能是当我们想要在引发事件的视觉/逻辑上处理事件时使用它。但这只是理论。
在实践中,我为什么要隧道事件?
隧道(和冒泡)是否也适用于逻辑树或视觉树或两者?
我发现隧道事件对于处理我自己没有创建的元素上的事件非常有用,因此没有简单的方法来添加事件处理程序。例如,ItemsControl
基于模板生成 UI 元素,因此获取这些元素的引用并不总是一个简单的过程。与其为生成的每个项目添加事件处理程序,不如ItemsControl
在单个父元素上处理隧道事件。
路由事件遍历“混合”树,它既不是可视树也不是逻辑树。这听起来有点疯狂,但过去从未给我带来任何问题。
隧道事件在 WPF 中用于所有 OnPreview 事件。如果您希望实际的目标元素是最后一个接收事件的元素,则隧道是有意义的。
如果您有一个列表框,其中包含一个包含文本框的项目。单击文本框将消耗单击,因此不会选择列表框。如果您使用隧道或预览鼠标单击事件,您可以先选择,不处理,然后移动到文本框。另请注意,在 WPF 中,如果未处理预览事件,则每个事件都将首先触发预览,然后触发气泡事件。
女士号码:
隧道:最初,调用元素树根处的事件处理程序。然后,路由事件沿着路由穿过连续的子元素,到达作为路由事件源的节点元素(引发路由事件的元素)。隧道路由事件通常作为控件合成的一部分使用或处理,这样来自合成部件的事件可以被故意抑制或替换为特定于整个控件的事件。WPF 中提供的输入事件通常以隧道/冒泡对的形式实现。由于对使用的命名约定,隧道事件有时也称为预览事件。
AFAIK Visual 树用于遍历,但由于 MSDN 已关闭,我无法寻找合适的来源。
这是来自MSDN的引用:
隧道:最初,调用元素树根处的事件处理程序。然后,路由事件沿着路由穿过连续的子元素,到达作为路由事件源的节点元素(引发路由事件的元素)。隧道路由事件通常作为控件合成的一部分使用或处理,这样来自合成部件的事件可以被故意抑制或替换为特定于整个控件的事件。WPF 中提供的输入事件通常以隧道/冒泡对的形式实现。由于对使用的命名约定,隧道事件有时也称为预览事件。
隧道事件就是通常所说的Preview
事件。
您可能还想阅读有关高级 WPF 的 MSDN 文章:了解 WPF 中的路由事件和命令。@Robert Havery
在这里对类似的问题写了一个很好的解释。
用户交互通常由成对的事件表示——一个预览交互(隧道),一个对交互做出反应(冒泡)。拥有隧道“预览”事件首先允许父控件拦截交互。
例如,如果您要创建自己的按钮样式用户控件,则控件的一部分可能是图标。如果用户单击该图标,您将拦截隧道单击预览事件,因为该图标不需要知道它已被单击。然后,您可以引发一个冒泡事件,通知包含您的按钮的任何控件它已被单击。