现在的位置: 首页 > 综合 > 正文

WPF学习之路由事件

2018年03月19日 ⁄ 综合 ⁄ 共 2784字 ⁄ 字号 评论关闭

来源:http://wodejiawww.blog.163.com/blog/static/81260833201291212927893/

WPF中新添加了一种事件---路由事件

路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码(如果用传统的方式实现一个操作,执行过个事件的调用则需要执行代码将事件串连起来方可)

路由事件的路由策略:

所谓的路由策略就是指:路由事件实现遍历元素的方式,总共有三种:

Bubbling(冒泡)

Tunneling(管道传递)

Direct(直接)

一、冒泡:

例:


WPF学习之路由事件 - wodejiawww - wodejiawww的博客WPF学习之路由事件 - wodejiawww - wodejiawww的博客XAML 

<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>


 


WPF学习之路由事件 - wodejiawww - wodejiawww的博客WPF学习之路由事件 - wodejiawww - wodejiawww的博客code 

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被点击");
        }
    }
}


 

我们会发现当点击button按钮时,button,Grid,window中的事件都会触发,这就是冒泡路由策略的功能所在,事件首先在源元素上触发,然后从每一个元素向上沿着树传递,直到到达根元素为止(或者直到处理程序把事件标记为已处理为止),从而调用这些元素中的路由事件。

事件标记为已处理的情况为:如果把button的事件修改为:

private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Button被点击");
e.Handled = true;
}

则以上事件就不会沿着button-grid-window执行下去,而是只执行button的事件。

如果在以上代码的基础上,还要执行grid 的事件的话,那就需要修改代码:

public Window1()
{
InitializeComponent();
grid.AddHandler(Grid.MouseDownEvent, new RoutedEventHandler(Grid_MouseDown1), true);
}

然后添加这个新事件Grid_MouseDown1

private void Grid_MouseDown1(object sender, RoutedEventArgs e)
{
MessageBox.Show("Grid被点击");
}

这样就是冒泡式

二、管道事件:

事件首先是从根元素上被触发,然后从每一个元素向下沿着树传递,直到到达源元素为止(或者直到到达处理程序把事件标记为已处理为止)

他的执行方式正好与冒泡式的相反。

例子:

还是上面的代码,只需要修改xaml


WPF学习之路由事件 - wodejiawww - wodejiawww的博客WPF学习之路由事件 - wodejiawww - wodejiawww的博客XAML 

<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>


 

特别值得注意的是:管道事件按照惯例,他们的名字中都有一个preview前缀,一般来说管道事件都有他的配对的冒泡事件,例如:PreviewMouseDown和MouseDown就是配对事件,如果同时存在的话,那么就会先执行管道事件然后才执行配对的冒泡事件。

三、直接:

事件仅仅在源元素上触发,这个与普通的.Net事件的行为相同,不同的是这样的事件仍然会参与一些路由事件的特定机制,如事件触发器等。

该事件唯一可能的处理程序是与其挂接的委托。

路由事件的事件处理程序的签名:

他与通用的.net事件处理程序的模式一致,也有两个参数:第一个为:System.Object对象,名为sender,第二个参数(一般名为e)是一个派生于System.EventArgs的类。sender参数就是该处理程序被添加的元素,参数e是RoutedEventArgs的一个实例提供了4个有用的属性:

Source---逻辑树中开始触发该事件的的元素。

originalSource--可视树中一开始触发该事件的元素。

handled---布尔值,设置为true表示事件已处理,在这里停止。

RoutedEvent---真正的路由事件对象,(如Button.ClickEvent)当一个事件处理程序同时用于多个路由事件时,它可以有效地识别被出发的事件。

抱歉!评论已关闭.