与传统的桌面开发相比,在事件模型上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. (四)u-boot2013.01.01 for TQ210:《mkconfig分析》

    config.mk主要功能是配置单板信息和编译环境,将会被u-boot的makefile所调用,本文仍然侧重于句法分析. ####################################### ...

  2. IE浏览器部分版本不支持opacity透明度属性问题

    半透明部分设置样式:opacity:0.7在ie9/ie10/ff/chrome/opera/safari显示正常. 但是这样在ie6-ie8中是不支持的,需要加上下面这句话: filter: pro ...

  3. Kinect For Windows V2开发日志九:侦测并绘制人体骨架

    简介 在上一篇<侦测.追踪人体骨架>里,介绍了关节点的使用办法,这一篇记录将关节点与OpenCV结合的绘图方法. 代码 #include <iostream> #include ...

  4. IOS学习网站

    http://www.cocoachina.com http://onevcat.com/#blog http://objccn.io http://blog.devtang.com http://b ...

  5. Matlab之cell使用

    1.声明 (1) DataCell = cell(1,N);(2) DataCell{N} = []; 如何赋值呢? a{1,1}=rand(5) 那么a的1行1列的单元中存储的就是一个随机的5×5的 ...

  6. 【CSS3】---块状元素、内联元素(又叫行内元素)和内联块状元素

    元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div>.<p>.<h1&g ...

  7. C# 输出24小时格式时间

    比如   MessageBox.Show(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")); 会输出  2014-4-3 5:08:4[1 ...

  8. Shell脚本报错unary operator expected

    在匹配字符串时用了类似这样的语句 if[ $timeofday = "yes"]; then echo "Good morning" exit 0 报错的原因是 ...

  9. CCNA的RIP路由学习

    rip(routing infomation protocol,路由信息协议) ,是一个纯粹的距离矢量路由选择协议,RIP每隔30s就将自己完整的路由选择表从所有激活的接口上送出.RIP只将跳计数作为 ...

  10. php中使用PHPExcel操作excel(xls)文件

    读取中文的xls.csv文件会有问题,网上找了下资料,发现PHPExcel类库好用,官网地址:http://phpexcel.codeplex.com/ 1.读取xls文件内容  代码如下 复制代码 ...