WPF是一款由微软公司自行研发的专门用来处理图形界面显示方面的开发工具。可以轻松的帮助开发人员实现与MAC相媲美的界面效果。在这里我们就先来了解一下WPF路由事件相关概念。#t#
我们创建一个WPF应用程序,代码如下:
- < Window x:Class="Wpfceshi.
Window1" - xmlns="http://schemas.microsoft.
com/winfx/2006/xaml/presentation" - xmlns:x="http://schemas.
microsoft.com/winfx/2006/xaml" - Title="Window1" Height="300"
Width="300" MouseDown=
"Window_MouseDown" > - < Grid MouseDown="Grid_MouseDown"
x:Name="grid"> - < Button Height="30" Width="100"
Content="点击我" MouseDown=
"Button_MouseDown"/> - < /Grid>
- < /Window>
- using System.Windows;
- using System.Windows.Input;
- namespace Wpfceshi
- {
- /// < summary>
- /// Window1.xaml 的交互逻辑
- /// < /summary>
- public partial class Window1 : Window
- {
- public Window1()
- {
- InitializeComponent();
- }
- private void Window_MouseDown
(object sender, MouseButtonEventArgs e) - {
- MessageBox.Show("Window被点击");
- }
- private void Grid_MouseDown
(object sender, MouseButtonEventArgs e) - {
- MessageBox.Show("Grid被点击");
- }
- private void Button_MouseDown
(object sender, MouseButtonEventArgs e) - {
- MessageBox.Show("Button被点击");
- }
- }
- }
调试运行,鼠标右键点击按钮,会依次弹出三个对话框。(注意一定是鼠标右键,否则引发不了事件)
这里大家也许就会问了,我点击的是按钮,为什么Grid和Window也会引发事件呢?其实这就是WPF路由事件的机制,引发的事件由源元素逐级传到上层的元素,Button—>Grid—>Window,这样就导致这几个元素都接收到了事件。
那么如何让Grid和Window不处理这个事件呢?
我们只需要在Button_MouseDown这个方法中加上e.Handled = true; 这样就表示事件已经被处理,其他元素不需要再处理这个事件了。
- private void Button_MouseDown
(object sender, MouseButton
EventArgs e)- {
- MessageBox.Show("Button被点击");
- e.Handled = true;
- }
这时如果我们需要Grid也参与处理这个事件该怎么做呢?我们只需要给他AddHandler即可。
修改代码如下
- public Window1()
- {
- InitializeComponent();
- grid.AddHandler(Grid.
MouseDownEvent, new
RoutedEventHandler
(Grid_MouseDown1), true);- }
再加上这个方法
- private void Grid_MouseDown1
(object sender, RoutedEventArgs e)- {
- MessageBox.Show("Grid被点击");
- }
到此大家应该对WPF路由事件有大概的认识了吧。
上面我们看到的只是路由事件中的一种方式:气泡。还有两种:隧道、直接。
总结:
气泡事件是WPF路由事件中最为常见,它表示事件从源元素扩散(传播)到可视树,直到它被处理或到达根元素。这样您就可以针对源元素的上方层级对象处理事件。例如,您可向嵌入的 Grid 元素附加一个 Button.Click 处理程序,而不是直接将其附加到按钮本身。气泡事件有指示其操作的名称(例如,MouseDown)。隧道事件采用另一种方式,从根元素开始,向下遍历元素树,直到被处理或到达事件的源元素。这样上游元素就可以在事件到达源元素之前先行截取并进行处理。根据命名惯例,隧道事件带有前缀 Preview(例如 PreviewMouseDown)。
直接事件类似 .NET Framework 中的正常事件。该事件***可能的处理程序是与其挂接的委托。
对于WPF路由事件中的隧道事件,大家可以写个小程序测试一下
- < Window x:Class="Wpfceshi.
Window1"- xmlns="http://schemas.
microsoft.com/winfx/2006/xaml/
presentation"- xmlns:x="http://schemas.
microsoft.com/winfx/2006/xaml"- Title="Window1" Height="300"
Width="300" PreviewMouseDown=
"Window_PreviewMouseDown" >- < Grid PreviewMouseDown=
"Grid_PreviewMouseDown"
x:Name="grid">- < Button Height="30" Width="100"
Content="点击我" PreviewMouseDown=
"Button_PreviewMouseDown"/>- < /Grid>
- < /Window>
- using System.Windows;
- using System.Windows.Input;
- namespace Wpfceshi
- {
- /// < summary>
- /// Window1.xaml 的交互逻辑
- /// < /summary>
- public partial class Window1 : Window
- {
- public Window1()
- {
- InitializeComponent();
- }
- private void Button_PreviewMouseDown
(object sender, MouseButtonEventArgs e)- {
- MessageBox.Show("Button被点击");
- }
- private void Grid_PreviewMouseDown
(object sender, MouseButtonEventArgs e)- {
- MessageBox.Show("Grid被点击");
- }
- private void Window_PreviewMouseDown
(object sender, MouseButtonEventArgs e)- {
- MessageBox.Show("Window被点击");
- }
- }
- }
可以看到,隧道事件的传递刚好与WPF路由事件中的气泡事件相反。