路由事件通过EventManager,RegisterRoutedEvent方法注册,通过AddHandler和RemoveHandler来关联和解除关联的事件处理函数;通过RaiseEvent方法来触发事件;通过传统的CLR事件来封装后供用户使用。

如何实现自定义路由事件,可以参考MSDN官网上的文档:如何:创建自定义路由事件

下面的这个demo参考自<葵花宝典--WPF自学手册>。

1、MainWindow.xaml

 <Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="518" Width="525"
local:MySimpleButton.CustomClick="InsertList"
Loaded="Window_Loaded">
<Grid Name="grid1" local:MySimpleButton.CustomClick="InsertList">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions>
<local:MySimpleButton x:Name="simpleBtn" CustomClick="InsertList" >
MySimpleBtn
</local:MySimpleButton>
<ListBox Name="lstMsg" Grid.Row="1"></ListBox>
<CheckBox Grid.Row="2" Name="chkHandle">Handle first event</CheckBox>
<Button Grid.Row="3" Click="cmdClear_Click">Clear list</Button>
</Grid> </Window>

在xaml文件中,完成页面的元素布局之后,给几个元素添加了事件处理函数。

(1)给Window添加了Loaded事件的处理函数,还添加了MySimpleButton的CustomClick事件的类事件处理函数

 local:MySimpleButton.CustomClick="InsertList"
Loaded="Window_Loaded"

(2)给Grid同样添加了MySimpleButton的类事件处理函数

(3)给MySimpleButton元素添加了CustomClick事件的实例事件处理函数

CustomClick="InsertList" 

(4)给Button元素添加了Click事件处理函数

Click="cmdClear_Click"

2、MySimpleButton.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows; namespace WpfApplication1
{
//继承Button类,自定义一个名为MySimpleButton的Button
public class MySimpleButton:Button
{
//———————————类事件处理函数————————————
static MySimpleButton()
{
//为路由事件CustomClickEvent注册一个类事件处理函数
//类事件处理函数的优先权高于实例事件处理函数
EventManager.RegisterClassHandler(typeof(MySimpleButton), CustomClickEvent, new RoutedEventHandler(CustomClickClassHandler), false);
}
//创建一个名为CustomClickClassHandler的类事件处理函数
//为了通知外部窗口,把路由事件的信息输出,需要添加一个普通的CLR事件ClassHandlerProcessed
public event EventHandler ClassHandlerProcessed;
public static void CustomClickClassHandler(object sender, RoutedEventArgs e)
{
MySimpleButton simpleBtn = sender as MySimpleButton;
EventArgs args = new EventArgs();
simpleBtn.ClassHandlerProcessed(simpleBtn, args);
} //———————————实例事件处理函数————————————
//创建和注册一个名为CustomClickEvent的路由事件,路由策略为Bubble
public static readonly RoutedEvent CustomClickEvent = EventManager.RegisterRoutedEvent("CustomClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MySimpleButton));
//给路由事件添加一个CLR事件包装器
public event RoutedEventHandler CustomClick
{
add
{
AddHandler(CustomClickEvent, value);
}
remove
{
RemoveHandler(CustomClickEvent, value);
}
}
//RaiseEvent()触发CustomClickEvent事件
protected override void OnClick()
{
RaiseCustomClickEvent();
}
void RaiseCustomClickEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(MySimpleButton.CustomClickEvent);
RaiseEvent(newEventArgs);
} }
}

这个是自定义的一个按钮类,在里面创建了自定义的路由事件。

3、MainWindow.xaml.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//MySimpleButton的类事件处理函数处理过,window就能得到通知
this.simpleBtn.ClassHandlerProcessed += new EventHandler(simpleBtn_RaisedClass);
}
protected int eventCount = ;
//CusomClick的事件处理函数
private void InsertList(object sender, RoutedEventArgs e)
{
eventCount++;
string msg = "#" + eventCount.ToString() + ":\r\n" + "InsertList\r\n" + "Sender:" + sender.ToString() + "\r\n Source:" + e.Source+"\r\n"+"Original Source:"+e.OriginalSource;
lstMsg.Items.Add(msg);
//CheckBox选中状态表示路由事件是否已处理,若已处理,则不在传递
e.Handled = (bool)chkHandle.IsChecked;
}
//类事件处理函数已经完成,打印信息
private void simpleBtn_RaisedClass(object sender, EventArgs e)
{
eventCount++;
string msg = "#" + eventCount.ToString() + ":\r\n WindowClassHandler\r\nSender:" + sender.ToString();
lstMsg.Items.Add(msg);
}
//Clear列表内容
private void cmdClear_Click(object sender, RoutedEventArgs e)
{
eventCount = ;
lstMsg.Items.Clear();
}
//在window的Load事件中给Grid另外添加一个名为ProcessHandlersToo的路由事件处理函数
//通过这种方式添加,即使路由事件被标记"已处理",处理函数仍然会执行
private void Window_Loaded(object sender, RoutedEventArgs e)
{
grid1.AddHandler(MySimpleButton.CustomClickEvent, new RoutedEventHandler(ProcessHandlerToo), true);
} private void ProcessHandlerToo(object sender, RoutedEventArgs e)
{
eventCount++;
string msg = "#" + eventCount.ToString() + ":\r\n" + "InsertList\r\n" + "Sender:" + sender.ToString() + "\r\n Source:" + e.Source + "\r\n" + "Original Source:" + e.OriginalSource;
lstMsg.Items.Add(msg); }
}
}

上面是路由事件的具体处理。

4、运行效果

从上面的运行效果可以看到,

(1)CheckBox未选中

路由事件在传递时,首先被类事件处理函数处理,然后沿着视觉树向上传递(MySimpleButton-->Grid-->Window),依次被添加了实例事件处理函数的元素进行事件处理。在传到Grid元素时,先进行InserList处理,再进行ProcessHandlerToo处理,这两个事件处理函数是用不同方式添加的,执行顺序不同。

(2)CheckBox选中

选中了CheckBox,则路由事件传递到MySimpleButton元素并进行处理后,被标记成"已处理",则之后不再向上传递,Grid和Window元素不再执行InsertList,但是Grid中的处理函数ProcessHandlerToo仍然会执行,这是两种事件添加方式不同的地方。

WPF:自定义路由事件的实现的更多相关文章

  1. WPF自定义路由事件(二)

    WPF中的路由事件 as U know,和以前Windows消息事件区别不再多讲,这篇博文中,将首先回顾下WPF内置的路由事件的用法,然后在此基础上自定义一个路由事件. 1.WPF内置路由事件 WPF ...

  2. 细说WPF自定义路由事件

    WPF中的路由事件 as U know,和以前Windows消息事件区别不再多讲,这篇博文中,将首先回顾下WPF内置的路由事件的用法,然后在此基础上自定义一个路由事件. 1.WPF内置路由事件   W ...

  3. WPF 自定义路由事件

    如何:创建自定义路由事件 首先自定义事件支持事件路由,需要使用 RegisterRoutedEvent 方法注册 RoutedEvent C#语法 public static RoutedEvent ...

  4. Wpf自定义路由事件

    创建自定义路由事件大体可以分为三个步骤: ①声明并注册路由事件. ②为路由事件添加CLR事件包装. ③创建可以激发路由事件的方法. 以ButtonBase类中代码为例展示这3个步骤: public a ...

  5. WPF自定义路由事件(一)

    首先自定义事件支持事件路由,需要使用 RegisterRoutedEvent 方法注册 RoutedEvent C#语法 public static RoutedEvent RegisterRoute ...

  6. WPF 自定义路由事件 与 附加路由事件

    为student添加附件事件

  7. WPF自学入门(四)WPF路由事件之自定义路由事件

    在上一遍博文中写到了内置路由事件,其实除了内置的路由事件,我们也可以进行自定义路由事件.接下来我们一起来看一下WPF中的自定义路由事件怎么进行创建吧. 创建自定义路由事件分为3个步骤: 1.声明并注册 ...

  8. WPF路由事件三:自定义路由事件

    与依赖项属性类似,WPF也为路由事件提供了WPF事件系统这一组成.为一个类型添加一个路由事件的方式与为类型添加依赖项属性的方法类似,添加一个自定义路由事件的步骤: 一.声明路由事件变量并注册:定义只读 ...

  9. WPF的路由事件、冒泡事件、隧道事件(预览事件)

    本文摘要: 1:什么是路由事件: 2:中断事件路由: 3:自定义路由事件: 4:为什么需要自定义路由事件: 5:什么是冒泡事件和预览事件(隧道事件): 1:什么是路由事件 WPF中的事件为路由事件,所 ...

随机推荐

  1. 大一上学期C语言学习心得总结

    经过一个学期的C语言学习,大体算是在这个编程语言上入了门,能够通过一些代码解决特定的问题.当然,每次成功将问题转换成代码都小有激动,虽然只是在黑框上输出了一些数字或是字符串. 编程,虽然还不是很懂,但 ...

  2. JSF JQUERY 使用datepicker

    不推荐使用.可以用primefaces的p:Calendar替代,更换控制使用. 简单使用jquery的datepicker示例: <!doctype html> <html lan ...

  3. python运维开发之路02

    年底事多,在公司忙成狗,难得把博客更新了下 本章主要内容是collections模块的介绍(队列,计数器,默认字典,有序字典,可命名元组,以及简单介绍深浅拷贝!) collections模块 coll ...

  4. 谈谈 ES6 的 Promise 对象

    https://segmentfault.com/a/1190000002928371 前言 开篇首先设想一个日常开发常常会遇到的需求:在多个接口异步请求数据,然后利用这些数据来进行一系列的操作.一般 ...

  5. 9月22日下午JavaScript----Document对象

    document对象 一.找元素 1.根据id找 示例: <input id = "a" type="button" value="找元素&qu ...

  6. php mysql实体字符

    问题描述:php提交数据的时候遇到特殊符号,需要转义才可以提交数据 如:提交单引号,双引号... php代码: $str = "我但是'sdf6448"; $data['goods ...

  7. $this->display输出模板

    1.public function index(){ $this->display() } // 默认输出的是index.html模板 2.public function index(){ $t ...

  8. HTML5 常用的结构化标签整理

    一.语义化结构化标签 结构化标签优点: 1.方便浏览器处理和识别,提升了网页的质量和语义. 2.减少了大量无意义的div标签,增强代码的可读性. 结构化标签:(header,nav,body,arti ...

  9. JavaScript数据操作--原始值和引用值的操作本质

    我的一句话总结:原始值不管是变量赋值还是函数传递都不会改变原值,引用值不管是变量赋值还是函数传递,如果新变量重新赋值,则不会影响原引用值,如新变量是直接操作,就会影响原引用值. 首先明确,值和类型是两 ...

  10. sqlserver下载

    https://msdn.microsoft.com/zh-cn/sqlserver/default.aspx