WPF学习之路(四)路由
功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。
实现定义:路由事件是一个 CLR 事件,可以由RouteEvent 类的实例提供支持并由 Windows Presentation Foundation (WPF) 事件系统来处理。
实例:
Xaml
<Border Height="" Width="" BorderBrush="Gray" BorderThickness="">
<StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
<Button Name="YesButton" Width="Auto" >Yes</Button>
<Button Name="NoButton" Width="Auto" >No</Button>
<Button Name="CancelButton" Width="Auto" >Cancel</Button>
</StackPanel>
</Border>
在这个简化的元素树中,Click事件的源是某个 Button元素,而所单击的 Button是有机会处理该事件的第一个元素。 但是,如果附加到 Button的任何处理程序均未作用于该事件,则该事件将向上冒泡到元素树中的 Button父级(即 StackPanel)。 该事件可能会冒泡到 Border,然后会到达元素树的页面根(未显示出来)。
换言之,此Click事件的事件路由为:Button-->StackPanel-->Border-->...
路由事件的策略
Bubbling:路由事件随后会路由到后续的父元素,直到到达元素树的根。
Direct:只有源元素本身才有机会调用处理程序以进行响应
Tunneling:最初将在元素树的根处调用事件处理程序。
路由事件策略会因为一下因素改变:
事件处理函数
public delegate void RoutedEventHandler(Object Sender, RoutedEventArgs e);
public delegate void MouseEventHandler(Object Sender, MouseEventArgs e);
RoutedEventArgs和MouseEventArgs包含路由事件的信息
如果设置"Handled"属性为True,路由事件会停止传递
类和实例事件处理函数
事件处理函数有两种类型,前一种是普通事件处理函数,"实例事件处理函数",另一种是通过EventManager.RegisterClassHandler方法将一个事件处理函数和类关联起来,"类事件处理函数",优先级更高
实例:(取自《葵花宝典--WPF自学手册》6.5)
自定义Button类
public class MySimpleButton : Button
{
static MySimpleButton()
{
EventManager.RegisterClassHandler(typeof(MySimpleButton), CustomClickEvent, new RoutedEventHandler(CustomClickClassHandler), false);
} public event EventHandler ClassHandlerProcessed;
public static void CustomClickClassHandler(Object sender, RoutedEventArgs e)
{
MySimpleButton simpBtn = sender as MySimpleButton;
EventArgs args = new EventArgs();
simpBtn.ClassHandlerProcessed(simpBtn, e);
} //Create and register routed event, routing strategies: Bubble
public static readonly RoutedEvent CustomClickEvent = EventManager.RegisterRoutedEvent(
"CustomClick",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(MySimpleButton)); //CLR event wrapper
public event RoutedEventHandler CustomClick
{
add { AddHandler(CustomClickEvent, value); }
remove { RemoveHandler(CustomClickEvent, value); }
} //Raise CustomClickEvent
void RaiseCustomClickEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(MySimpleButton.CustomClickEvent);
RaiseEvent(newEventArgs);
} //Onclick
protected override void OnClick()
{
RaiseCustomClickEvent();
} }
MainWindow.xaml
<Window x:Class="Alex_WPFAPPDemo02.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:Alex_WPFAPPDemo02"
custom:MySimpleButton.CustomClick="InsertList"
Title="MainWindow" Height="" Width="">
<Grid Margin="" custom:MySimpleButton.CustomClick="InsertList" Name="Grid1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<custom:MySimpleButton x:Name="simpBtn" CustomClick="InsertList">
My Simple Button
</custom:MySimpleButton>
<ListBox Margin="" Name="listBox" Grid.Row="" />
<CheckBox Margin="" Grid.Row="" Name="chkHandle">
Handle first event
</CheckBox>
<Button Grid.Row="" HorizontalAlignment="Right" Margin="" Padding="" Click="clear">
Clear List
</Button>
</Grid>
</Window>
MainWindow.xaml.cs
protected int eventCounter = ;
private void InsertList(object sender, RoutedEventArgs e)
{
eventCounter++;
string message = "#" + eventCounter.ToString() + ":\r\n"
+ "InsertList\r\n"
+ " Sender: " + sender.ToString() + "\r\n"
+ " Source: " + e.Source + "\r\n"
+ "Original Source: " + e.OriginalSource;
listBox.Items.Add(message);
e.Handled = (bool)chkHandle.IsChecked;
} private void clear(object sender, RoutedEventArgs e)
{
eventCounter = ;
listBox.Items.Clear();
}
添加类处理函数
static MySimpleButton()
{
EventManager.RegisterClassHandler(typeof(MySimpleButton), CustomClickEvent, new RoutedEventHandler(CustomClickClassHandler), false);
} public event EventHandler ClassHandlerProcessed;
public static void CustomClickClassHandler(Object sender, RoutedEventArgs e)
{
MySimpleButton simpBtn = sender as MySimpleButton;
EventArgs args = new EventArgs();
simpBtn.ClassHandlerProcessed(simpBtn, e);
}
完善代码
public MainWindow()
{
InitializeComponent();
this.simpBtn.ClassHandlerProcessed += new EventHandler(ButtonRaisedClass);
}private void ButtonRaisedClass(object sender, EventArgs e)
{
eventCounter++;
string message = "#" + eventCounter.ToString() + ":\r\n"
+ "Windows Class Handler\r\n"
+ " Sender: " + sender.ToString();
listBox.Items.Add(message);
} private void ProcessHanldersToo(Object sender, RoutedEventArgs e)
{
eventCounter++;
string message = "#" + eventCounter.ToString() + ":\r\n"
+ "ProcessHanldersToo\r\n"
+ " Sender: " + sender.ToString()
+ " Source: " + e.Source + "\r\n"
+ "Original Source: " + e.OriginalSource;
listBox.Items.Add(message);
} private void Window_Loaded(object sender, RoutedEventArgs e)
{
Grid1.AddHandler(MySimpleButton.CustomClickEvent, new RoutedEventHandler(ProcessHanldersToo), true);
}

可以查看路由事件的线路
To be continue...
WPF学习之路(四)路由的更多相关文章
- WPF学习之路初识
WPF学习之路初识 WPF 介绍 .NET Framework 4 .NET Framework 3.5 .NET Framework 3.0 Windows Presentation Found ...
- Redis——学习之路四(初识主从配置)
首先我们配置一台master服务器,两台slave服务器.master服务器配置就是默认配置 端口为6379,添加就一个密码CeshiPassword,然后启动master服务器. 两台slave服务 ...
- WPF学习之路(十四)样式和模板
样式 实例: <Window.Resources> <Style x:Key="BtnStyle"> <Setter Property=" ...
- WPF学习(6)路由事件
做过.net开发的朋友对于事件应该都不陌生.追溯历史,事件(Event)首先应用在Com和VB上,它是对在MFC中使用的烦琐的消息机制的一个封装,然后.net又继承了这种事件驱动机制,这种事件也叫.n ...
- 【WPF学习】第四十三章 路径和几何图形
前面四章介绍了继承自Shape的类,包括Rectangle.Ellipse.Polygon以及Polyline.但还有一个继承自Shape的类尚未介绍,而且该类是到现在为止功能最强大的形状类,即Pat ...
- 【WPF学习】第四十九章 基本动画
在前一章已经学习过WPF动画的第一条规则——每个动画依赖于一个依赖项属性.然而,还有另一个限制.为了实现属性的动态化(换句话说,使用基于时间的方式改变属性的值),需要有支持相应数据类型的动画类.例如, ...
- WPF学习之路(八)页面
传统的应用程序中有两类应用程序模式:桌面应用,Web应用.WPF的导航应用程序模糊了这两类应用程序的界限的第三类应用程序 WPF导航表现为两种形式,一是将导航内容寄宿于窗口,二是XAML浏览器应用程序 ...
- WPF学习之路(二) XAML(续)
属性 简单属性 前面用到的Width/Height都是简单属性,其赋值一定要放到双引号里 XAML解析器会根据属性的类型执行隐式转换 与C#的区别 SolidBrush.Color = Colors. ...
- WPF学习之路(一) 初识WPF
参考<葵花宝典-WPF自学手册> VS2012 先创建第一个WPF小程序 1.创建WPF程序 2.查看Solution,WPF中xaml文件和cs文件经常成对出现 两个主要的类:APP(W ...
随机推荐
- 使用CKplayer插件在网页中嵌入视频的方法(常用笔记2)
在做网站中有时候我们需要在网页中嵌入视频,一般视频嵌入有以下几种方法: 1. 优酷代码嵌入 优点:简单,方便,可靠. 缺点:有广告,现在的网站非常注重用户体验,如果打开一个在线视频是有长广告的一定会崩 ...
- SingalR--demo
原文链接 : http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and ...
- XE7 提交 App(iOS 8)提示「does not contain the correct beta entitlement」问题修复
XE7 提交 App 后,在「Prerelease」里被提示了: Build 1.0.0 does not contain the correct beta entitlement. For more ...
- 通过指定函数/方法形参类型提高PHP代码可靠性
指定形参类型是PHP 5就支持的一项特性.形参支持array - 数组. object - 对象两种类型. class User{ public $name; public $password; fu ...
- 第 22 章 CSS3 渐变效果
学习要点: 1.线性渐变 2.径向渐变 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS3 背景渐变功能,主要有两种渐变方式:线性渐变和径向(放射性)渐变. 一.线性渐变 CSS3 提供了 li ...
- 第 19 章 CSS 其他样式
学习要点: 1.颜色和透明度 2.盒子阴影和轮廓 3.光标样式 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 其他剩下几个常用的样式,包括颜色.透明度.盒子的阴影轮廓以及光标的样式. 一.颜 ...
- Guava学习笔记:Guava cache
缓存,在我们日常开发中是必不可少的一种解决性能问题的方法.简单的说,cache 就是为了提升系统性能而开辟的一块内存空间. 缓存的主要作用是暂时在内存中保存业务系统的数据处理结果,并且等待下次访问使用 ...
- webapi的返回类型,webapi返回图片
1.0 首先是返回常用的系统类型,当然这些返回方式不常用到.如:int,string,list,array等.这些类型直接返回即可. public List<string> Get() { ...
- tomcat jdk servlet websocket版本对应关系
最近在考虑公司主要基础三方库版本统一和升级的问题,特看了下tomcat jdk servlet websocket版本的对应关系,如下:
- AES .net 、JS 相互加密解密
/// <summary> /// AES加密 /// </summary> public class AES { /// <summary> /// 加密 /// ...