Button—Grid—Window

时间:2022-06-05 03:30:44

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

举个例子:

Button—Grid—Window

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

举个例子:

Button—Grid—Window

既然WPF中使用这样的一个设计理念,路由事件就是出格为WPF而生,它的成果就是可以把一个事件从触发点沿着树向上或者向下流传,需要对这个事件作出反响的处所就添加一个监听器,就会有相应的反响,固然,它的通报是可以用代码来遏制。 好了,我已经概略了解了一些路由事件。下面先来了解一下WPF内置的路由事件和道理,然后我们来创建一个属于本身的路由事件。

1、WPF内置的路由事件

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

Button—Grid—Window

添加后置代码

Button—Grid—Window

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

ButtonMouseDown事件被触发:

Button—Grid—Window

GridMouseDown事件被触发:

Button—Grid—Window

WindowMouseDown事件被触发:

Button—Grid—Window

我点击的是按钮,为什么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的初学者,如有不同错误的处所,欢迎在评论区多多指教,学习,为了分享,,为了提高。