路由事件概述

功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。

实现定义:路由事件是一个 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学习之路(四)路由的更多相关文章

  1. WPF学习之路初识

    WPF学习之路初识   WPF 介绍 .NET Framework 4 .NET Framework 3.5 .NET Framework 3.0 Windows Presentation Found ...

  2. Redis——学习之路四(初识主从配置)

    首先我们配置一台master服务器,两台slave服务器.master服务器配置就是默认配置 端口为6379,添加就一个密码CeshiPassword,然后启动master服务器. 两台slave服务 ...

  3. WPF学习之路(十四)样式和模板

    样式 实例: <Window.Resources> <Style x:Key="BtnStyle"> <Setter Property=" ...

  4. WPF学习(6)路由事件

    做过.net开发的朋友对于事件应该都不陌生.追溯历史,事件(Event)首先应用在Com和VB上,它是对在MFC中使用的烦琐的消息机制的一个封装,然后.net又继承了这种事件驱动机制,这种事件也叫.n ...

  5. 【WPF学习】第四十三章 路径和几何图形

    前面四章介绍了继承自Shape的类,包括Rectangle.Ellipse.Polygon以及Polyline.但还有一个继承自Shape的类尚未介绍,而且该类是到现在为止功能最强大的形状类,即Pat ...

  6. 【WPF学习】第四十九章 基本动画

    在前一章已经学习过WPF动画的第一条规则——每个动画依赖于一个依赖项属性.然而,还有另一个限制.为了实现属性的动态化(换句话说,使用基于时间的方式改变属性的值),需要有支持相应数据类型的动画类.例如, ...

  7. WPF学习之路(八)页面

    传统的应用程序中有两类应用程序模式:桌面应用,Web应用.WPF的导航应用程序模糊了这两类应用程序的界限的第三类应用程序 WPF导航表现为两种形式,一是将导航内容寄宿于窗口,二是XAML浏览器应用程序 ...

  8. WPF学习之路(二) XAML(续)

    属性 简单属性 前面用到的Width/Height都是简单属性,其赋值一定要放到双引号里 XAML解析器会根据属性的类型执行隐式转换 与C#的区别 SolidBrush.Color = Colors. ...

  9. WPF学习之路(一) 初识WPF

    参考<葵花宝典-WPF自学手册> VS2012 先创建第一个WPF小程序 1.创建WPF程序 2.查看Solution,WPF中xaml文件和cs文件经常成对出现 两个主要的类:APP(W ...

随机推荐

  1. Needham-Schroeder加密算法小结

    自己整理了下关于Needham-Schroeder加密算法的相关知识,如下图示.

  2. win8.1安装Team Function Server 2013

    1.系统是Win8.1企业版64位 2.Visual Studio 2013 3.数据库是Sql Server2012 (这里注意需要升级到SP1否则安装可能失败下载地址http://www.micr ...

  3. JSON的简单例子

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 下载JSON所需要的jar文件并加入工程后,编写如下代码: package com.hzhi.json; ...

  4. XMPP客户端开发(1)--连接和登录

    Smack可用于XMPP客户端的开发,下载Smack,将相关jar文件导入后,即可以开始XMPP客户端的开发. 以下代码实现了客户端连接Tigase服务器,并根据用户名和密码登录. package X ...

  5. 基于TCP和多线程实现无线鼠标键盘-Socket(1)

    把手机作为移动鼠标.键盘使用非常方便,本文将实现这一功能.该应用分为两部分:Windows服务端和Android客户端. 本文源代码的下载地址:http://download.csdn.net/det ...

  6. python3.4怎么连接mysql pymysql连接mysql数据库

    本文介绍了python3 4连接mysql数据库的方法,在python3 4中使用原来python2 7的mysqldb已不能连接mysql数据库了,可以使用pymysql.   在python3.4 ...

  7. ahjesus code simith 存储过程模板

    <%------------------------------------------------------------------------------------------ * Au ...

  8. java 编译时的初始化顺序

    有的时候,java的初始化会对我的工作照成很大影响,所以简单介绍一下, 首先介绍简单的变量的初始化:在类的内部,变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义之间,它也会先于构造器和 ...

  9. TreeSet集合深入了解--------攻击原理

    Set接口Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.(无序,不可重复 )Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说 ...

  10. c# tabcontrol事件以及上下文菜单

    今天在搞中间件的客户端管理工具时,遇到需要管理tabcontrol子页的问题,希望在右击标签页是弹出关闭.关闭其他的提示框,如下所示: 可通过增加一个ContextMenuStrip,并在tabCon ...