路由事件概述

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

实现定义:路由事件是一个 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. IBM和传统IT的沦落

    传统IT厂商沦落已经成为一种趋势.不仅仅是在中国去IOE的大背景下,在全球范围内,这些曾经盛极一时的IT大鳄也在衰落.作为一个在IBM服务了将近14年的老员工,我想浅谈一下IBM以及整个传统IT行业的 ...

  2. EF更新,数据库值变化,前台页面并不变化,刷新也不变化,重新运行程序则变化----开发中遇到的问题(已解决)

    首先说一下我遇到这个情况的代码情景,首先上错误代码 UserInfo userInfo = Session["UserInfo"] as UserInfo; ); 这段代码所呈现的 ...

  3. Abot 爬虫分析-整体结构

    1. 引言 在Github 上搜索下Web Crawler 有上千个开源的项目,但是C#的仅仅只有168 个,相比于Java 或者Python 确实少的可怜.如果按照Stars 排名.可以看到 排在第 ...

  4. sql中 in , not in , exists , not exists效率分析

    in和exists执行时,in是先执行子查询中的查询,然后再执行主查询.而exists查询它是先执行主查询,即外层表的查询,然后再执行子查询. exists 和 in 在执行时效率单从执行时间来说差不 ...

  5. 多态(RAW)

    函数重写overwrite:当子类提供了和父类同名的虚函数时,称之为函数重写,函数的返回值类 函数名 参数列表必须完全相同 名字隐藏namehide:当子类提供了和父类同名的数据时 叫名字隐藏 函数重 ...

  6. javascript模板库jsrender for循环嵌套示例

    最近在参与整合前端的框架,我们知道javascript最强大的模板引擎之一当属jsrender,号称下一代jquery模板引擎的标准实现. 通常在模板merge的过程中,我们会遇到两次乃至三级嵌套的情 ...

  7. HBase集群安装过程中的问题集锦

    1.HRegionServer启动不正常 在namenode上执行jps,则可看到hbase启动是否正常,进程如下: [root@master bin]# jps26341 HMaster26642 ...

  8. crystal

    1.在*{margin:0;padding:0;}下,标签自带样式会失去效果,如:blockquote.table下cellpadding,align等. 2.标签自带属性样式没有css高. 3.在c ...

  9. 【再探backbone 02】集合-Collection

    前言 昨天我们一起学习了backbone的model,我个人对backbone的熟悉程度提高了,但是也发现一个严重的问题!!! 我平时压根没有用到model这块的东西,事实上我只用到了view,所以昨 ...

  10. [deviceone开发]-一个很炫的手势动画示例

    一.简介 这是iOS下的效果,android下完全一致.通过do_GestureView组件和do_Animation组件,deviceone能很容易实现复杂的跨平台纯原生动画效果,这个示例就是通过手 ...