zoukankan      html  css  js  c++  java
  • WPF路由事件学习(一)

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

    路由事件的路由策略:

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

    Bubbling(冒泡)

    Tunneling(管道传递)

    Direct(直接)

    一、冒泡:

    例:

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

     我们会发现当点击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

     <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就是配对事件,如果同时存在的话,那么就会先执行管道事件然后才执行配对的冒泡事件。当然e.Handled=true,依然能够阻断事件。

    三、直接:

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

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

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

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

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

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

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

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

  • 相关阅读:
    矩阵的阶
    python中'0b111'中的b 是什么意思
    Python字节码介绍
    多版本python共存,安装三方库到指定python版本
    关于python 中的__future__模块
    解决Python模块报错:ModuleNotFoundError: No module name 'StringIO'
    python常用魔法函数
    MySQL binlog
    MySQL start and stop
    Mysql 源码安装
  • 原文地址:https://www.cnblogs.com/fuchongjundream/p/3836182.html
Copyright © 2011-2022 走看看