路由事件概述

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

实现定义:路由事件是一个 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. 基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式

    在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交,方便页面和服务器后端进行数据的交互处理.本文主要介绍利用Jquery处理数据交互的几种方式,包括 ...

  2. sql 内连接和外链接

    如表     -------------------------------------------------     table1 | table2 |     ----------------- ...

  3. 对TabControl的简单优化

    之前由于忙于赶项目进度而忽视了软件的用户体验,界面挺难看,有一天看见组长优化了某个窗体,让人感觉完全不一样,我也不甘示弱,要把我的程序做顺眼一点才行.我的程序是一个以TabControl为主要容器的窗 ...

  4. js中获取URL中指定的查询字符串

    js中获取URL中指定的搜索字符串,主要利用location对象实现,废话少说,上代码. function getSearchString(key) { // 获取URL中?之后的字符 var str ...

  5. 第 27 章 CSS 传统布局[下]

    学习要点: 1.定位布局 2.box-sizing 3.resize 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 早期所使用的传统布局,很多情况下,这些布局方式还是非常有用的. 一.定位布 ...

  6. struts工程建立配置细节

    ActionForm ActionForm是用于存放表单提交的数据. 1.一个action是否必须配置一个actionForm,可以没有2.一个action是否可以配置多个表单?不可以,最多一个 在j ...

  7. ubuntu15.10_x64 安装 nginx

      浏览器到 http://nginx.org/en/download.html 下载 stable version的nginx 如nginx-1.10.1.tar.gz,这是一个nginx源码包,需 ...

  8. 使用 JavaScript 实现灵活的固定导航功能

    如果你想在网页中实现灵活的固定导航功能,那么 Smart Fixed Navigation 这个 JavaScript 小脚本可以帮助轻松实现一个固定的导航,让用户在访问你的网站的时候可以随时使用菜单 ...

  9. Unsplash.it - 实用的图片占位符,支持个性化设置

    Unsplash.it 是一个使用漂亮的图像作为占位符的工具.只要把你的图像尺寸(宽与高)放到网址后面的参数中,你会得到一个占位符.你可以很容易地得到一个随机图像或者是一个模糊图像.也支持获取灰度图像 ...

  10. javascript使浏览器关闭前弹出确认

    当用户关闭页面时,弹出对话框,让用户确认是否关闭,选择确定则页面关闭,否则页面不关闭. 效果体验:http://keleyi.com/keleyi/phtml/js/index.htm 完整代码: & ...