WPF学习02:Routed Events
与传统的桌面开发相比,在事件模型上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种事件路由模式:
- Direct (不路由)
- Bubbling events(向上路由)
- 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的更多相关文章
- 【WPF学习】第五十七章 使用代码创建故事板
在“[WPF学习]第五十章 故事板”中讨论了如何使用代码创建简单动画,以及如何使用XAML标记构建更复杂的故事板——具有多个动画以及播放控制功能.但有时采用更复杂的故事板例程,并在代码中实现全部复杂功 ...
- WPF学习开发客户端软件-任务助手(下 2015年2月4日代码更新)
时光如梭,距离第一次写的 WPF学习开发客户端软件-任务助手(已上传源码) 已有三个多月,期间我断断续续地对该项目做了优化.完善等等工作,现在重新向大家介绍一下,希望各位可以使用,本软件以实用性为主 ...
- 天脉2(ACoreOS653)操作系统学习02
天脉2(ACoreOS653)操作系统学习02 一.分区内通信方法 分区内通信指同一分区内进程之间的通信.ARINC 653定义的分区内进程通信机制,包括:缓存队列(Buffers-Queue).黑板 ...
- JavaScript学习02 基础语法
JavaScript学习02 基础语法 JavaScript中很多基础内容和Java中大体上基本一样,所以不需要再单独重复讲了,包括: 各种算术运算符.比较运算符.逻辑运算符: if else语句.s ...
- Java虚拟机JVM学习02 类的加载概述
Java虚拟机JVM学习02 类的加载概述 类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对 ...
- Python学习02 列表 List
Python学习02 列表 List Python列表 List Python中的列表(List)用逗号分隔,方括号包围(comma-separated values (items) between ...
- Android Testing学习02 HelloTesting 项目建立与执行
Android Testing学习02 HelloTesting 项目建立与执行 Android测试,分为待测试的项目和测试项目,这两个项目会生成两个独立的apk,但是内部,它们会共享同一个进程. 下 ...
- Routed Events【pluralsight】
Routing Strategies: Direct Bubbling Tunneling WHy use them? Any UIElement can be a listener Common h ...
- WPF学习05:2D绘图 使用Transform进行控件变形
在WPF学习04:2D绘图 使用Shape绘基本图形中,我们了解了如何绘制基本的图形. 这一次,我们进一步,研究如何将图形变形. 例子 一个三角形,经Transform形成组合图形: XAML代码: ...
随机推荐
- C++中模板函数或模板类中关键词class和typename
##区别 基本上来说,class和typename几乎没有区别.在可以使用class的地方都可以使用typename,在使用typename的地方也几乎可以使用class. 可以看出我加黑了两个子:几 ...
- Ralink RT3290无线网卡驱动安装 (linux)
Ralink RT3290无线网卡驱动安装 (linux, 笔记备忘) 1. 设备信息查看无线网卡设备信息 # lspci : 2. 驱动下载http://pan.baidu.com/s/1sjsHN ...
- Jira安装部署
一.先安装JDK JDK1.6下载:http://www.java.net/download/jdk6/6u10/promoted/b32/binaries/jdk-6u10-rc2-bin-b32- ...
- 当“逻辑”与“UE”冲突时
如上图. 权限系统有三个对象:用户.角色和组. 角色代表自定义的权限集合. "组"你可以理解为"文件夹"."部门"等名词. 一个用户可以拥有 ...
- asp.net 之 GC (垃圾回收机制)
今天抽时间好好整理了下GC相关知识,看了CSDN和博客园的几篇文章,有了一定的简单了解,决定根据个人理解整合一份随笔写下来,望诸位指教. 一:基础问题 1.首先需要知道了解什么是GC? GC如其名,就 ...
- ASP.NET缓存全解析4:应用程序数据缓存 转自网络原文作者李天平
System.Web.Caching 命名空间提供用于缓存服务器上常用数据的类.此命名空间包括 Cache 类,该类是一个字典,您可以在其中存储任意数据对象,如哈希表和数据集.它还为这些对象提供了失效 ...
- 苹果宣布首批HomeKit智能家居设备将在6月上市
凤凰科技讯 北京时间5月15日消息,据<华尔街日报>网络版报道,苹果周四宣布,首批支持其HomeKit平台的智能家居设备将在下月上市.这一消息的发布也驳斥了关于该苹果家庭自动化软件平台将推 ...
- C# Ajax 手机发送短信验证码 校验验证码 菜鸟级别实现方法
1.Ajax请求处理页面: using System; using System.Collections.Generic; using System.Linq; using System.Web; u ...
- ORACLE 对用户密码做限制
1. 查看默认设置 2. PASSWORD_LIFE_TIME 60 --口令的生命周期,超过这段时间口令可能会自动过期,是否过期要看是否设定了PASSWORD_GRACE_TIME PASSWORD ...
- Objective-C 【This is ARC】
------------------------------------------- ARC的概念及原理 (1)指针分类 强指针:默认情况下,所有的指针都是强指针,关键字strong 弱指针:_ _ ...