我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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自定义路由事件内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

WPF自定义路由事件的示例分析

这篇文章主要为大家展示了“WPF自定义路由事件的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“WPF自定义路由事件的示例分析”这篇文章吧。一、声明路由事件变量并注册定义只读的静态变量字段
2023-06-29

WPF中隧道路由和冒泡路由事件的示例分析

这篇文章主要介绍了WPF中隧道路由和冒泡路由事件的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由
2023-06-14

WPF自定义控件的实现

本文主要介绍了WPF自定义控件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-03

Node.js自定义实现文件路由功能

一、创建路由处理定义 //获取http模块 var http = require('http'); //文件 模块 var fs = require('fs'); //404文件 var error = "./view/404.h
2022-06-04

Nodejs中自定义事件实例

其实就是继承events的EventEmitter就可以了,然后就可以通过on去注册事件;emit去触发事件,removeListener去移除事件,简单例子如下:var util = require('util'); var Et = r
2022-06-04

SpringBoot自定义路由覆盖实现流程详解

这篇文章主要介绍了SpringBoot自定义路由覆盖实现流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2023-01-02

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

一、基础 很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章。先总结下自定义View的步骤: 1、自定义View的属性
2022-06-06

JAVA用户自定义事件监听实例代码

JAVA用户自定义事件监听实例代码很多介绍用户自定义事件都没有例子,或是例子不全,下面写了一个完整的例子,并写入了注释以便参考,完整的实例源代码如下:package demo;import Java.util.EventObject;/**
2023-05-31

MVC路由自定义及视图找寻规则的示例分析

这篇文章将为大家详细讲解有关MVC路由自定义及视图找寻规则的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。MVC路由自定义相信对于MVC路由的配置大家也都了解过一些,其实,这也不是本章的重点。创建
2023-06-17

spring boot 自定义starter的实现教程

spring boot 使用 starter 解决了很多配置问题, 但是, 他是怎么来解决这些问题的呢这里通过一个简单的例子, 来看一下, starter是怎么来设置默认配置的.一. 建 starter 项目自定义的starter, 项目命
2023-05-30

Android App开发中自定义View和ViewGroup的实例教程

View Android所有的控件都是View或者View的子类,它其实表示的就是屏幕上的一块矩形区域,用一个Rect来表示,left,top表示View相对于它的parent View的起点,width,height表示View自己的宽高
2022-06-06

使用Spring自定义注解实现任务路由的方法

在Spring mvc的开发中,我们可以通过RequestMapping来配,当前方法用于处理哪一个URL的请求.同样我们现在有一个需求,有一个任务调度器,可以按照不同的任务类型路由到不同的任务执行器。其本质就是通过外部参数进行一次路由和S
2023-05-31

android开发教程之自定义控件checkbox的样式示例

主界面xml文件代码如下:2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录