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

路由事件的路由策略:

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

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)当一个事件处理程序同时用于多个路由事件时,它可以有效地识别被出发的事件。

WPF路由事件学习(一)的更多相关文章

  1. WPF自学入门(三)WPF路由事件之内置路由事件

    有没有想过在.NET中已经有了事件机制,为什么在WPF中不直接使用.NET事件要加入路由事件来取代事件呢?最直观的原因就是典型的WPF应用程序使用很多元素关联和组合起来,是否还记得在WPF自学入门(一 ...

  2. WPF路由事件二:路由事件的三种策略

    一.什么是路由事件 路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件.路由事件是一个CLR事件. 路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件 ...

  3. WPF 路由事件 Event Routing

    原文:WPF 路由事件 Event Routing 1.路由事件介绍 之前介绍了WPF的新的依赖属性系统,本篇将介绍更高级的路由事件,替换了之前的.net普通事件.相比.net的事件,路由事件具有更强 ...

  4. WPF路由事件

    ​    这节讲一下WPF中的路由事件(Routed Event). [什么是事件] 在了解路由事件前,我们应先来了解一下什么是事件(Event). 在Windows系统中,像鼠标单击,双击,移动这样 ...

  5. WPF 路由事件总结

    1.什么是路由事件 已下为MSDN中的定义 功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件. 实现定义:路由事件是一个 CLR 事件,可以由 R ...

  6. .NET: WPF 路由事件

    (一)使用WPF内置路由事件 xaml: <Window x:Class="WpfApplication1.MainWindow" xmlns="http://sc ...

  7. WPF自学入门(四)WPF路由事件之自定义路由事件

    在上一遍博文中写到了内置路由事件,其实除了内置的路由事件,我们也可以进行自定义路由事件.接下来我们一起来看一下WPF中的自定义路由事件怎么进行创建吧. 创建自定义路由事件分为3个步骤: 1.声明并注册 ...

  8. WPF路由事件三:自定义路由事件

    与依赖项属性类似,WPF也为路由事件提供了WPF事件系统这一组成.为一个类型添加一个路由事件的方式与为类型添加依赖项属性的方法类似,添加一个自定义路由事件的步骤: 一.声明路由事件变量并注册:定义只读 ...

  9. WPF 路由事件

    最近想封装一个关于手势的控件,但是由其他的控件覆盖之后发现不能触发,据说是有一些事件在定义的时候就处理过e.Handle了. 定义的时候就处理了,就是为了控件能够正常的工作,别如Button.Mous ...

随机推荐

  1. git 通过nginx 无法clone

    git服务器架设在内网,通过nginx做反向代理后如果公网质量差的话部分项目无法clone,报错: error: RPC failed; result=18, HTTP code = 200B | 3 ...

  2. 配置文件报错:不允许有匹配 [xX][mM][lL] 的处理指令目标。

    http://www.68idc.cn/help/buildlang/ask/20150108163110.html ————————————————————————————————————————— ...

  3. CSS条件注释

    由于浏览器版本的不同,对CSS里某些元素的解释也不一样,针对浏览器版本不同而选择不同CSS的代码,其实我们还可以利用条件注释的方法来达到类似的目的,什么是条件注释,在此简单介绍一下,无非就是一些if判 ...

  4. MySql避免重复插入记录的几种方法

    本文章来给大家提供三种在mysql中避免重复插入记录方法,主要是讲到了ignore,Replace,ON DUPLICATE KEY UPDATE三种方法,有需要的朋友可以参考一下 方案一:使用ign ...

  5. VMware Ubuntu NAT 不能上网

    在VMware中配置NAT,控制面板->网络和Internet->网络连接,设置对应的VMware网卡为DHCP. ubuntu虚拟机中配置网卡为DHCP.获取不到ip. 参考链接: ht ...

  6. CSS之float vs position:absolute

    补充:ul 应该设置下 list-style: none; 题外话:看了张鑫旭的视频,这家伙把简单的css玩出了新花样,绝对大神级的存在.膜拜下先~ float的作用前面一章已经说过了,但没考虑过的是 ...

  7. JDBC WHERE子句条件实例

    在本教程将演示如何在JDBC应用程序中,从数据库表中查询数据记录, 在查询选择记录时使用WHERE子句添加其他条件. 在执行以下示例之前,请确保您已经准备好以下操作: 具有数据库管理员权限,以在给定模 ...

  8. ASP.NET MVC Castle Windsor 教程

    一.[转]ASP.NET MVC中使用Castle Windsor 二.[转]Castle Windsor之组件注册 平常用Inject比较多,今天接触到了Castle Windsor.本篇就来体验其 ...

  9. (个人)CentOS的JDK安装

    一. 卸载JDK 1. 通过如下命令查看当前JDK的相关内容 rpm -qa | grep java 2. 如果出现如下内容 java-1.7.0-openjdk-1.7.0.9-2.3.4.1.el ...

  10. 二维数组按某个键值排序 FOR PHP

    $arr=[ array( 'name'=>'小坏龙', 'age'=>28 ), array( 'name'=>'小坏龙2', 'age'=>14 ), array( 'na ...