欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF自学入门(三)WPF路由事件之内置路由事件

程序员文章站 2022-04-06 13:11:48
有没有想过在.NET中已经有了事件机制,为什么在WPF中不直接使用.NET事件要加入路由事件来取代事件呢?最直观的原因就是典型的WPF应用程序使用很多元素关联和组合起来,是否还记得在WPF自学入门(一)XAM基本知识中提到过两棵树,逻辑树LogicalTree 和可视化树 VisualTree,那么 ......

       有没有想过在.NET中已经有了事件机制,为什么在WPF中不直接使用.NET事件要加入路由事件来取代事件呢?最直观的原因就是典型的WPF应用程序使用很多元素关联和组合起来,是否还记得在WPF自学入门(一)XAM基本知识中提到过两棵树,逻辑树LogicalTree 和可视化树 VisualTree,那么它们分别是什么?

举个例子:

WPF自学入门(三)WPF路由事件之内置路由事件

上面的代码就是逻辑树LogicalTree,一个Grid里面镶嵌了其他控件或布局组件,相当于一棵树中的叶子。而可视化树VisualTree是什么?它就是一个树中的树叶里面的结构,用放大镜看一下,其实叶子里面的结构也是一颗树结构

举个例子:

WPF自学入门(三)WPF路由事件之内置路由事件

       既然WPF中使用这样的一个设计理念,路由事件就是特别为WPF而生,它的功能就是可以把一个事件从触发点沿着树向上或者向下传播,需要对这个事件作出反应的地方就添加一个监听器,就会有相应的反应,当然,它的传递是可以用代码来停止。 好了,我已经大概了解了一些路由事件。下面先来了解一下WPF内置的路由事件和原理,然后我们来创建一个属于自己的路由事件。

1、WPF内置的路由事件

      新建WPF项目,在页面上放置按钮。然后在Window,Grid,Button标签上使用MouseDown事件,如下图

WPF自学入门(三)WPF路由事件之内置路由事件

添加后置代码

WPF自学入门(三)WPF路由事件之内置路由事件

调试运行,鼠标右键点击按钮,会依次弹出下列三个对话框。

ButtonMouseDown事件被触发:

WPF自学入门(三)WPF路由事件之内置路由事件

 

GridMouseDown事件被触发:

WPF自学入门(三)WPF路由事件之内置路由事件

 

WindowMouseDown事件被触发:

WPF自学入门(三)WPF路由事件之内置路由事件

 

       我点击的是按钮,为什么Grid和Window也会引发事件呢?其实这就是路由事件的机制,引发的事件由源元素逐级传到上层的元素,Button—>Grid—>Window,这样就导致这几个元素都接收到了事件。(注意一定是鼠标右键,否则引发不了事件。

      如果想Grid和Window不处理这个事件,只需要在Button_MouseDown这个方法中加上e.Handled = true; 这样就表示事件已经被处理,其他元素不需要再处理这个事件了。

 private void Button_MouseDown(object sender, MouseButtonEventArgs e)

  {

            MessageBox.Show("Button被点击!");

            e.Handled = true;

   }

        如果想要Grid参与事件处理只需要给它AddHandler即可

grid.AddHandler(Grid.MouseDownEvent, new RoutedEventHandler(Grid_MouseDown), true);

        到这里我想大家应该对路由事件有了大概认识了。路由事件实际上分两类:气泡事件和预览事件(也叫做隧道事件)。上文中的例子就是气泡事件。

2、内置路由事件学习总结:

     气泡事件是WPF路由事件中最为常见,它表示事件从源元素扩散传播到可视树,直到它被处理或到达根元素。这样我们就可以针对源元素的上方层级对象处理事件。(例如MouseDown)

     预览事件采用另一种方式,从根元素开始,向下遍历元素树,直到被处理或到达事件的源元素。这样上游元素就可以在事件到达源元素之前先行截取并进行处理。根据命名惯例,预览事件带有前缀 Preview(例如 PreviewMouseDown)。

     气泡事件和预览事件区别

     气泡事件:在Button上点击,首先弹出“Button”,再弹出“Grid”,最后弹出“Window”。

     预览事件:在Button上点击,首先弹出“Window”,再弹出“Grid”,最后弹出“Button”。

     看到了这个顺序区别,那么我们加入e.Handled=true的时机也要不同

 

PS:本人也是WPF的初学者,如有不对的地方,欢迎在评论区多多指教,学习,为了分享,为了提高。