服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - WPF自定义路由事件的实例教程

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

2022-12-01 12:04Charles_Su C#

WPF中有两种事件模型,一种是在WinForm时代就存在的CLR事件,另一种是WPF时代的路由事件,这篇文章主要给大家介绍了关于WPF自定义路由事件的相关资料,需要的朋友可以参考下

路由事件模型

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

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

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

【分析代码】

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

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

代码一

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

代码二

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

代码三

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

代码四

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

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

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

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

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

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

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

【自定义路由事件】

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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的声明:

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

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

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

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

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

运行效果如下:

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

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

总结

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

原文链接:https://www.cnblogs.com/charlesmvp/p/15230150.html

延伸 · 阅读

精彩推荐
  • C#unity实现翻页按钮功能

    unity实现翻页按钮功能

    这篇文章主要为大家详细介绍了unity实现翻页按钮功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    贪玩的孩纸时代11952022-09-02
  • C#C#扩展方法实例分析

    C#扩展方法实例分析

    这篇文章主要介绍了C#扩展方法,结合实例形式分析了C#扩展方法的功能、使用方法及相关注意事项,需要的朋友可以参考下...

    傻丫头与科技9182022-01-10
  • C#Unity3D UGUI特效之Image高斯模糊效果

    Unity3D UGUI特效之Image高斯模糊效果

    这篇文章主要为大家详细介绍了Unity3D UGUI特效之Image高斯模糊效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    苏小败在路上12222022-03-11
  • C#C#的TimeSpan案例详解

    C#的TimeSpan案例详解

    这篇文章主要介绍了C#的TimeSpan案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    十年河东,十年河西,莫4152022-11-30
  • C#C#实现字符串倒序的写法

    C#实现字符串倒序的写法

    这篇文章主要为大家详细介绍了C#实现字符串倒序的多种写法,以LINQ写法最为简洁,感兴趣的朋友可以参考一下...

    zhangbaochong6672021-11-22
  • C#WPF简单的数据库查询实例

    WPF简单的数据库查询实例

    下面小编就为大家分享一篇WPF简单的数据库查询实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    happy多乐4802022-02-12
  • C#C#使用LitJson解析JSON的示例代码

    C#使用LitJson解析JSON的示例代码

    本篇文章主要介绍了C#使用LitJson解析JSON的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    peiandsky6312021-12-22
  • C#C#实现绑定Combobox的方法

    C#实现绑定Combobox的方法

    这篇文章主要介绍了C#实现绑定Combobox的方法,涉及Combobox参数设置的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    我心依旧10702021-10-22