与传统的桌面开发相比,在事件模型上WPF引入了Routed Events,从开发者的角度上,我们获得了两个便利:

  1.可以实现事件路由,即向XAML结构中的父元素路由或者是向子元素路由。

2. RoutedEventArgs作为默认的事件Args为我们提供了更多的信息。

事件应用示例

  建立工程“RoutedEvent”,初始的代码修改Grid Layout为StackPanel,添加了一个Button,如下图:

   

  编写Click Event Handler:

 private void ButtonA_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Get it");
}

  我们有两种方式为该按钮添加Click Event Handler:

  XAML形式:

 <Button Name="ButtonA" Click="ButtonA_Click">ButtonA</Button>

  C#形式:

 ButtonA.AddHandler(Button.ClickEvent, new RoutedEventHandler(ButtonA_Click));
ButtonA.Click += ButtonA_Click; //这样亦可,但只能用于该控件支持的事件

  结果:

  

  注意:一个事件,同一个handler添加多次的结果如下图,是引发Bug的诱因之一:

  

  

RoutedEventArgs

  从上一个例子我们可以看到,WPF事件机制默认提供的EventArgs为RoutedEventArgs

 public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);

  与EventArgs相比,Routed Event提供了4个新的属性.

  RoutedEvent:可以获取到时间的类型,可以在一个Handler处理多个不同类型事件时用上。

  其它三个都与事件路由相关:

  Handled,指定sender是否对该事件继续路由,接下来的例子会展示它的作用。

  Source,该事件的触发源。

  OriginalSource,通常与Source为同一个值。

  

事件路由

  以事件路由模式来分类,WPF提供了3种事件路由模式:

  1. Direct (不路由)
  2. Bubbling events(向上路由)
  3. Tunneling events(向下路由)

  对于一个事件,如果不清楚它的路由模式,可以MSDN查一下:比如:MSDN上关于Click的说明:

  

  直接以例子来说明事件路由的作用:我们修改一下XAML代码,如下:

 <StackPanel>
<Button Name="ButtonA">ButtonA</Button>
<Button Name="ButtonB">ButtonB</Button>
<Button Name="ButtonC">ButtonC</Button>
<Button Name="ButtonD">ButtonD</Button>
<Button Name="ButtonE">ButtonE</Button>
<Button Name="ButtonF">ButtonF</Button>
<Button Name="ButtonG">ButtonG</Button>
<Button Name="ButtonH">ButtonH</Button>
</StackPanel>

  现在界面上有了8个Button,如果需要为8个按钮都做事件处理,那要怎么做呢?通过事件路由我们可以很优雅的解决:

  由于Click为向上路由的事件,我们随便找它的一个父元素,比如stackPanel,填加一句代码就好了:

 <StackPanel Button.Click="Button_Click">

  以下为Handler代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Get Info From {0}", e.Source);
}

  结果:

  

  为顶层Window添加同样的代码会得到相同的结果,因为事件将一直路由到顶层。

  最后,回顾一下刚才RoutedEventArgs中的Handled.

  接下来的例子说明了如何通过设置Handled阻碍事件路由:

  XAML代码:

 <Window x:Class="RoutedEvent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Button.Click="Button_Click">
<StackPanel Name="StackPanelA">
<Button Name="ButtonA">ButtonA</Button>
<Button Name="ButtonB">ButtonB</Button>
<Button Name="ButtonC">ButtonC</Button>
<Button Name="ButtonD">ButtonD</Button>
<Button Name="ButtonE">ButtonE</Button>
<Button Name="ButtonF">ButtonF</Button>
<Button Name="ButtonG">ButtonG</Button>
<Button Name="ButtonH">ButtonH</Button>
</StackPanel>
</Window>

  C#代码:

  

 public MainWindow()
{
InitializeComponent();
StackPanelA.AddHandler(Button.ClickEvent, new RoutedEventHandler(StackPanel_Click), true);
} private void Button_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Get Info From {0}", e.Source);
} private void StackPanel_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("I will block the routing", e.Source);
e.Handled = true;
}

  结果:事件路由将到了StackPanel即被阻碍,Window的对于Click 的Handler将不会触发,大家可以试试。

WPF学习02:Routed Events的更多相关文章

  1. 【WPF学习】第五十七章 使用代码创建故事板

    在“[WPF学习]第五十章 故事板”中讨论了如何使用代码创建简单动画,以及如何使用XAML标记构建更复杂的故事板——具有多个动画以及播放控制功能.但有时采用更复杂的故事板例程,并在代码中实现全部复杂功 ...

  2. WPF学习开发客户端软件-任务助手(下 2015年2月4日代码更新)

    时光如梭,距离第一次写的 WPF学习开发客户端软件-任务助手(已上传源码)  已有三个多月,期间我断断续续地对该项目做了优化.完善等等工作,现在重新向大家介绍一下,希望各位可以使用,本软件以实用性为主 ...

  3. 天脉2(ACoreOS653)操作系统学习02

    天脉2(ACoreOS653)操作系统学习02 一.分区内通信方法 分区内通信指同一分区内进程之间的通信.ARINC 653定义的分区内进程通信机制,包括:缓存队列(Buffers-Queue).黑板 ...

  4. JavaScript学习02 基础语法

    JavaScript学习02 基础语法 JavaScript中很多基础内容和Java中大体上基本一样,所以不需要再单独重复讲了,包括: 各种算术运算符.比较运算符.逻辑运算符: if else语句.s ...

  5. Java虚拟机JVM学习02 类的加载概述

    Java虚拟机JVM学习02 类的加载概述 类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对 ...

  6. Python学习02 列表 List

    Python学习02 列表 List Python列表 List Python中的列表(List)用逗号分隔,方括号包围(comma-separated values (items) between ...

  7. Android Testing学习02 HelloTesting 项目建立与执行

    Android Testing学习02 HelloTesting 项目建立与执行 Android测试,分为待测试的项目和测试项目,这两个项目会生成两个独立的apk,但是内部,它们会共享同一个进程. 下 ...

  8. Routed Events【pluralsight】

    Routing Strategies: Direct Bubbling Tunneling WHy use them? Any UIElement can be a listener Common h ...

  9. WPF学习05:2D绘图 使用Transform进行控件变形

    在WPF学习04:2D绘图 使用Shape绘基本图形中,我们了解了如何绘制基本的图形. 这一次,我们进一步,研究如何将图形变形. 例子 一个三角形,经Transform形成组合图形: XAML代码: ...

随机推荐

  1. 【Shell脚本学习9】Shell替换:Shell变量替换,命令替换,转义字符

    如果表达式中包含特殊字符,Shell 将会进行替换.例如,在双引号中使用变量就是一种替换,转义字符也是一种替换. 举个例子: #!/bin/bash a=10 echo -e "Value ...

  2. Oracle安装步骤及PL/SQL Developer连接数据库

    一:Oracle安装步骤及PL/SQL Developer连接数据库 win7 64位 11g 点击(操作步骤):http://www.cnblogs.com/haoke/articles/27343 ...

  3. java处理高并发高负载类网站的优化方法

    java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据) 一:高并发高负载类网站关注点之数据库 没错,首先是数据库,这是大多数应用所面临的首个SPOF ...

  4. Freebsd 编译内核

    # cd /usr/src/sys/i386/conf # cp GENERIC GENERIC.20060812# ee GENERIC 如果要加入ipf防火墙的话则加入options        ...

  5. CF 107E 多边形面积并

    107E Darts 题目:给出n个矩形,问落在n个矩形交的部分的概率 分析:裸的多边形面积并. 代码略..

  6. php-fpm参数调优

    关于php-fpm.conf参数调优,只对重要的参数进程调优.其它可参数前辈的. http://php.net/manual/zh/install.fpm.configuration.php (官方的 ...

  7. Part 89 to 91 Talking about pass the parameters in thread

    Part 89   ParameterizedThreadStart delegate Use ParameterizedThreadStart delegate to pass data to th ...

  8. DWZ (JUI) 教程 国际化问题(多语言/语言切换)

    DWZ 国际化也是比较简单的,网站的内容国际化和常规的项目国际化是一样的,不要做出特殊的调整. DWZ 自身框架的国际化,比如 翻页的上一页下一页等信息.这些信息都是在dwz.frag.xml 文件当 ...

  9. JavaScript之动态背景登陆表单

    <!doctype html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  10. 研究validation插件到现在的感受

    1.比较累 2.看了几十个页面参考是有的,要抓住问题的实质,实质在于要改插件代码.因为它本身不提供这个方法. 3.对了,还没有描述这个问题,问题就是再次验证时,成功的样式不消失.解决方法如下: 修改了 ...