WPF路由事件三:自定义路由事件
与依赖项属性类似,WPF也为路由事件提供了WPF事件系统这一组成。为一个类型添加一个路由事件的方式与为类型添加依赖项属性的方法类似,添加一个自定义路由事件的步骤:
一、声明路由事件变量并注册:定义只读的静态变量字段RouteEvent类来声明一个变量,然后使用EventManager的RegisterRoutedEvent()方法向事件系统注册路由事件,该方法的签名如下:
1 public static RoutedEvent RegisterRoutedEvent(string name, RoutingStrategy routingStrategy, Type handlerType, Type ownerType);
该方法带有四个参树:
第一个参数name表示该路由事件在WPF事件系统中的名称。
第二个参数routingStrategy是RoutingStrategy类型的枚举值,标明了路由事件的路由策略,共三种策略:,第一种Bubble是冒泡策略,这种模式是从触发点向根节点传递,直到最外层。第二种是Direct就是传统的事件一样的。第三种是隧道策略,这和冒泡策略相反,向下传递。
第三个参数handlerType用来标明事件处理函数的类型。
第四个个参数ownerType则用来标明拥有该路由事件的类型。
EventManager的RegisterRoutedEvent()方法返回一个RoutedEvent类型的实例。一般情况下,该实例将由一个public static readonly字段所保存。
二、通过标准的.NET事件包装路由事件:事件包装器使用AddHandler方法来添加路由事件的调用程序,然后使用RemoveHandler来删除已经添加的调用程序。
三、创建可以激发路由事件的方法。
演示创建自定义路由事件:
1、新建用户控件,添加一个Button按钮,添加按钮的Click事件,XAML代码如下:
1 <UserControl x:Class="CustomWpfRouteEvent.RouteEventControl" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 mc:Ignorable="d" 7 d:DesignHeight="300" d:DesignWidth="300"> 8 <Grid> 9 <Button Height="30" Width="100" Content="调用路由事件" Click="Button_Click"></Button> 10 </Grid> 11 </UserControl>
2、在用户控件的后台代码中创建自定义路由事件,C#代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace CustomWpfRouteEvent 17 { 18 /// <summary> 19 /// RouteEventControl.xaml 的交互逻辑 20 /// </summary> 21 public partial class RouteEventControl : UserControl 22 { 23 public RouteEventControl() 24 { 25 InitializeComponent(); 26 } 27 28 //1、声明并注册路由事件,使用冒泡策略 29 public static readonly RoutedEvent MyClientEvent = EventManager.RegisterRoutedEvent("MyClick", 30 RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RouteEventControl)); 31 32 //2、通过.NET事件包装路由事件 33 public event RoutedEventHandler MyClick 34 { 35 add 36 { 37 AddHandler(MyClientEvent, value); 38 } 39 remove 40 { 41 RemoveHandler(MyClientEvent, value); 42 } 43 } 44 45 /// <summary> 46 /// 3、使用按钮的单击事件激发路由事件 47 /// </summary> 48 /// <param name="sender"></param> 49 /// <param name="e"></param> 50 private void Button_Click(object sender, RoutedEventArgs e) 51 { 52 RoutedEventArgs arg = new RoutedEventArgs(); 53 arg.RoutedEvent = MyClientEvent; 54 RaiseEvent(arg); 55 } 56 } 57 }
3、在主界面中引入新创建的用户控件,使用自定义的路由事件MyClick,并为MyClick事件编写调用的方法,XAML代码如下:
1 <Window x:Class="CustomWpfRouteEvent.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:u="clr-namespace:CustomWpfRouteEvent" 5 Title="演示自定义路由事件" Height="350" Width="525" WindowStartupLocation="CenterScreen"> 6 <Grid> 7 <u:RouteEventControl MyClick="RouteEventControl_MyClick"></u:RouteEventControl> 8 </Grid> 9 </Window>
4、RouteEventControl_MyClick方法的后台代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace CustomWpfRouteEvent 17 { 18 /// <summary> 19 /// MainWindow.xaml 的交互逻辑 20 /// </summary> 21 public partial class MainWindow : Window 22 { 23 public MainWindow() 24 { 25 InitializeComponent(); 26 } 27 28 private void RouteEventControl_MyClick(object sender, RoutedEventArgs e) 29 { 30 MessageBox.Show("Hello:" + e.Source.ToString()); 31 } 32 } 33 }
5、运行程序,单击Button按钮,效果如下所示: