zoukankan      html  css  js  c++  java
  • WPF学习之路由事件

    原文:http://www.cnblogs.com/lxy131/archive/2010/08/10/1796754.html

    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就是配对事件,如果同时存在的话,那么就会先执行管道事件然后才执行配对的冒泡事件

    三、直接:

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

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

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

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

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

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

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

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

  • 相关阅读:
    Nightmare Ⅱ HDU
    Full Tank? POJ
    2601 电路维修 (双端队列bfs优先队列bfs(最短路))
    Sudoku POJ
    Pushing Boxes POJ
    2501 矩阵距离 (bfs)
    【排序】绝境求生
    【排序】逆序对IV
    【排序】紧急集合
    【排序】常用排序法
  • 原文地址:https://www.cnblogs.com/xh831213/p/3688265.html
Copyright © 2011-2022 走看看