路由事件概述

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

实现定义:路由事件是一个 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. Win10 IoT C#开发 3 - GPIO Pin 控制发光二极管

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一篇文 ...

  2. MySQL使用二进制日志恢复数据库

    一.二进制日志简介 MySQL有不同类型的日志,其中二进制文件记录了所有对数据库的修改,如果数据库因为操作不当或其他原因丢失了数据,可以通过二进制文件恢复. 在my.ini文件中设置了log-bin, ...

  3. maven安装与配置(第一天学习笔记)

    Maven下载:http://maven.apache.org/ 1.首先要确保JDK已经安装与配置(注意:用的是apache-maven-3.3.3的JDK1.6不行,我用的是JDK1.8) 2.把 ...

  4. 第 29 章 CSS3 弹性伸缩布局[下]

    学习要点: 1.新版本 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS3 提供的用来实现未来响应式弹性伸缩布局方案,这里做一个初步的了解. 一.新版本 新版本的 Flexbox 模型是 201 ...

  5. C#如何在钉钉开发平台中创建部门

    钉钉是阿里巴巴专为中小企业和团队打造的沟通.协同的多端平台,钉钉开放平台旨在为企业提供更为丰富的办公协同解决方案.通过钉钉开放平台,企业或第三方合作伙伴可以帮助企业快速.低成本的实现高质量的移动微应用 ...

  6. 基于 jQuery 实现的精致作品集图片导航效果

    今天,我们要用 jQuery 来创建一个作品集图像的导航模板.我们的想法是,以分组的方式显示一组作品集,并通过二维的方式(水平/垂直)来浏览.任一箭头或当前图像下方的小盒子可以作为导航使用. 在线演示 ...

  7. Typecast 免费了!献给设计师们的礼物

    TypeCast 让你可以从 Fonts.com.TypeKit.FontDeck 和 Google 这些字体供应和商选择字体,而且能非常方便的比较这些字体使用效果.如果你想获得用户对这些字体效果的反 ...

  8. MySql基本概念(一)

    MySQL基本概念 一. 数据库系统概述: mysql是数据库系统的一种,下面是所有数据库系统中主要的组件. 数据库系统由硬件部分和软件部分构成,硬件主要用于存储数据库中的数据,包括计算机.存储设备. ...

  9. jQuery绑定事件的四种方式

      jQuery提供了多种绑定事件的方式,每种方式各有其特点,明白了它们之间的异同点,有助于我们在写代码的时候进行正确的选择,从而写出优雅而容易维护的代码.下面我们来看下jQuery中绑定事件的方式都 ...

  10. CSS3绘制六边形

    因为很简单,所以先总结一下:使用CSS3绘制六边形主要使用伪类:before和:after在源元素之前和之后再绘制两个元素,并利用css3的边框样式,将这两个元素变成三角形放置在源元素的两端即可. ( ...