WPF自定义路由事件的实例教程

目录
  • 路由事件模型
  • 【分析代码】
  • 【自定义路由事件】
  • 总结

路由事件模型

传统的简单事件模型中,在消息激发是将消息通过事件订阅的然后交给事件的相应者,事件的相应者使用事件的处理器来做出相应,这样就存在一个问题,用户控件内部的事件就不能被外界订阅,因为事件的宿主必须能够直接访问到事件的响应者。

路由事件的事件拥有者和事件的相应者之间则没有直接的显式订阅关系,事件的拥有者则只负责激发事件,事件将有谁相应它并不知道,事件的响应者则有事件的监听器,针对事件进行监听,当有此类事件传递至此事件响应者就使用事件处理器来相应事件并决定此事件是否继续传递。比如像上一个程序中的,点击“点我”以后事件就开始激发了,然后事件就会在控件树上进行传递,事件的响应者安装了监听器,当监听到这个事件进行响应,并决定这个事件是否继续传递。

了解了路由事件后,这节来学习一下如何自定义路由事件。

【分析代码】

在演示代码前,我们不妨先看一段Button按钮的Click路由事件源码,从源码中学习一下如何定义路由事件。

在ButtonBase中,跟Click路由事件相关的有如下四处代码:

代码一

代码二

代码三

代码四

第一段是声明了ClickEvent这一路由事件对象,这个不用多说;

第二段是声明了ClickEvent路由事件对象的包装器,它类似于属性的get,set,方便我们从外部把路由事件的处理器附加到路由事件上。当外部进行“+=”操作时,内部就会执行add块,将事件处理附加到Click路由事件上,反之执行“-=”操作时,会执行remove块中的内容;

第三段是构造方法中构建Click路由事件对象,跟创建依赖对象类似的是,路由事件对象的创建也不是直接new,而是通过EventManager类的RegisterRoutedEvent方法进行注册,该方法第一个参数是路由事件的名称,微软约定路由事件名称要跟路由事件对象的包装器名称一致,并且跟路由事件对象去掉Event后缀的字样也要一致。第二个参数是指路由事件的策略,也就是事件传播的形式,有如下三种枚举:

  • RoutingStrategy.Tunnel:隧道式,是指事件从最外层的控件开始路由,直到路由到控件自己,就像一条自上往下的隧道,从window控件一路通到当前触发事件的控件;
  • RoutingStrategy.Bubble:冒泡式,这个跟隧道式相反,它是从触发事件的控件向上传播,直到最上层停止;
  • RoutingStrategy.Direct:直通式,跟原始事件模型一样,不路由,直达事件处理器。

第三个参数是指定该路由事件的事件处理器是什么类型,第四个参数是指定该路由事件对象的宿主类型,第四个参数跟第一个参数共同用于路由事件对象的内部创建使用:构建hash code,确定路由事件对象唯一性,同依赖属性一致,在一个类中不能注册两个同名的路由事件对象。

第四段是激发Click路由事件的方法,事件参数就是在此方法中处理,它是路由事件传播之源。

【自定义路由事件】

下面我们就来根据以上语法,基于ButtonBase创建自己的Click路由事件:

public class MyRoutedEventArgs : RoutedEventArgs
    {
        public MyRoutedEventArgs(RoutedEvent routedEvent, object source)
            : base(routedEvent, source) { }

        public string RoutedMessage { get; set; }
    }

    public class MyButton : ButtonBase
    {

        public static readonly RoutedEvent MessageEvent =
           EventManager.RegisterRoutedEvent("Message", RoutingStrategy.Bubble,
               typeof(EventHandler<MyRoutedEventArgs>), typeof(MyButton));

        public event RoutedEventHandler Message
        {
            add { this.AddHandler(MessageEvent, value); }
            remove { this.RemoveHandler(MessageEvent, value); }
        }

        protected override void OnClick()
        {
            base.OnClick();

            MyRoutedEventArgs eventArgs =  new MyRoutedEventArgs(MessageEvent, this)
                                                { RoutedMessage = "自定义路由事件被触发了" };
            this.RaiseEvent(eventArgs);

        }
    }

上述代码中,我创建了一个MyButton,声明了一个MessageEvent路由事件对象,值得注意的是,RegisterRoutedEvent的第三个参数我用的是:

typeof(EventHandler<MyRoutedEventArgs>)

而非:

typeof(RoutedEventHandler)

因为RoutedEventHandler的参数跟我自定义的事件参数不一致,需要使用EventHandler的泛型版指定我的事件参数类型,下面是RoutedEventHandler的声明:

该参数类型是RoutedEventArgs,而我使用的是自定义的MyRoutedEventArgs类型。

XAML部分及事件处理器的代码为:

在外层Grid上设置MyButton的Message事件监听及处理器。

运行效果如下:

点击“你好”,弹出MessageBox提示“自定义路由事件被触发了”。

总结

到此这篇关于WPF自定义路由事件的文章就介绍到这了,更多相关WPF自定义路由事件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解WPF中的隧道路由和冒泡路由事件

    WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇开始整理事件的用法和什么是直接路由,什么是冒泡路由,以及什么是隧道路由. 事件最基本的用法 在基于事件驱动的开发中,把代码放在响应注册的事件的处理函数内,比如Click事件.MouseDown事件.MouseUp事件等等.每个控件响应自己的注册事件,有很多如果在事件上有相互关联和影响的事件,就要在一个业务逻辑里写比较多的代码.而路由事件主要的优势就是路由事件可以在元素树上进行传递,并且沿着

  • WPF自定义路由事件的实例教程

    目录 路由事件模型 [分析代码] [自定义路由事件] 总结 路由事件模型 传统的简单事件模型中,在消息激发是将消息通过事件订阅的然后交给事件的相应者,事件的相应者使用事件的处理器来做出相应,这样就存在一个问题,用户控件内部的事件就不能被外界订阅,因为事件的宿主必须能够直接访问到事件的响应者. 路由事件的事件拥有者和事件的相应者之间则没有直接的显式订阅关系,事件的拥有者则只负责激发事件,事件将有谁相应它并不知道,事件的响应者则有事件的监听器,针对事件进行监听,当有此类事件传递至此事件响应者就使用事

  • WPF 自定义雷达图开发实例教程

    自定义雷达图表如下: 1.创建UserControl,名为"RadarChartControl" 前台: <UserControl x:Class="WpfApplication2.RadarChartControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/win

  • WPF自定义路由事件

    与依赖项属性类似,WPF也为路由事件提供了WPF事件系统这一组成.为一个类型添加一个路由事件的方式与为类型添加依赖项属性的方法类似,添加一个自定义路由事件的步骤: 一.声明路由事件变量并注册 定义只读的静态变量字段RouteEvent类来声明一个变量,然后使用EventManager的RegisterRoutedEvent()方法向事件系统注册路由事件,该方法的签名如下: public static RoutedEvent RegisterRoutedEvent(string name, Rou

  • WordPress中设置Post Type自定义文章类型的实例教程

    什么是自定义post? 不要想当然的认为这里的post就是就是指博客中的文章,它只不过是一个文章类的代理词而已,甚至你还可以认为它是内容. 自定义模型是没有一个很标准的什么规定的,文章模型可以是你想的任何一个内容模型,就拿wordpress本身来说就内置了以下几个内容文章模型: 博客文章 页面 附件 修正 导航等 你可以这样去理解:它只要是想我们使用博客文章那样用来创建.编辑和储存数据的一种很灵活的内容形式. 不过在这里我还是需要提醒下,博客内置的post还是有点点不同的,你可以利用它含有分类.

  • Android App中自定义View视图的实例教程

    一.基础 很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 3.重写onMesure 4.重写onDraw 我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的. 1.自定义View的属性,首先在res/values/  下建立一个attrs.xm

  • WPF路由事件中的三种策略介绍

    什么是路由事件 路由事件是具有更强传播能力的事件,它可以在元素树中向上冒泡和向下隧道传播,并且能够沿着传播路径被事件处理程序来处理. 路由事件允许事件在某个元素上被处理,即使这个事件源自于另外一个元素.事件路由允许某个元素的事件由另外一个元素引发. 路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件.路由事件是一个CLR事件. 路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而

  • Java事件处理机制(自定义事件)实例详解

    Java事件处理机制 java中的事件机制的参与者有3种角色: 1.event object:事件状态对象,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中 2.event source:具体的事件源,比如说,你点击一个button,那么button就是event source,要想使button对某些事件进行响应,你就需要注册特定的listener. 3.event listener:对每个明确的事件的发生,都相应地定义一个明确的Java方法.这些方法都集

  • WPF路由事件之逻辑树和可视树遍历

    一.什么是逻辑树 逻辑树就是描述WPF界面元素的实际构成,它是由程序在XAML中所有的UI元素组成.最显著的特点就是由布局控件.或者其他常用的控件组成. <Window x:Class="WpfRouteEvent.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/win

  • Vue.js组件使用开发实例教程

    组件 组件可以扩展HTML元素,封装可重用的代码,在较高的层面上,组件是自定义元素,vue.js的编译器为它添加特殊功能,在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展. Vue.js的组件可以理解为预先定义好了行为的ViewModel类.一个组件可以预定义很多选项,但最核心的是以下几个: 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系. 初始数据(data):一个组件的初始数据状态.对于可复用的组件来说,这通常是私有的状态. 接受的外部参数(p

随机推荐