zoukankan      html  css  js  c++  java
  • 《深入浅出WPF》学习笔记之深入浅出话事件

    WPF的事件为路由事件,路由的环境为UI组件树(Visual Tree),Visual Tree由控件和控件的组成元素组成,事件可以在控件内部传递并处理。另一个树为Logical Tree,只包含布局控件和其他控件而不包括控件的组成元素。因此路由事件沿着Visual Tree传递。

    传统.Net开发中的直接事件模型的缺点

    事件拥有者和响应者必须建立订阅关系,如果想让事件向外层控件传递必须手动编写事件响应链,即每个控件都要订阅事件并向其他控件再次传递该事件。

    路由事件

    与依赖属性类似,每个路由事件都定义为static readonly修饰的RoutedEvent类型字段,并且字段名称添加Event后缀。同时添加CLR事件的add、remove的事件包装器,类型为RoutedEventhandler。监听路由事件的示例代码:

    //C#代码
    root.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));
    
    //XAML
    <StackPanel x:Name="root" Button.Click="Button_Click">

    创建自定义路由事件

    声明static readonly修饰的RoutedEvent类型字段,创建路由事件的CLR事件包装器,在适当的时候激活路由事件。

        public class ReportTimeButton:Button
        {
            public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent("ReportTime", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ReportTimeButton));
    
    
            public event RoutedEventHandler ReportTime
            {
                add { this.AddHandler(ReportTimeEvent, value); }
                remove { this.RemoveHandler(ReportTimeEvent, value); }
            }
    
            protected override void OnClick()
            {
                base.OnClick();
    
                this.RaiseEvent(new RoutedEventArgs(ReportTimeEvent,this));
            }
        }

    注册路由事件的名称要与CLR包装器的名称相同,当使用+=或-=操作符附加或删除CLR事件时将调用包装器的add方法和remove方法。路由的类型可以分为Bubble:冒泡事件,从事件激发者向上级一层一层路由。Tunnel:从UI树的根向事件激发着传递。Direct:模拟CLR事件,不进行路由,直接送达事件处理器。如果想让路由事件停止传递,只需设置RoutedEventArgs的Handled属性为true,表示这个事件已经处理了,将不在进行传递。使用RoutedEventArgs.OriginalSource获取触发事件的原始对象(可以获取到控件内部组件),RoutedEventArgs.Source获取事件路由中的上一个事件接受者。

    附加事件

    路由事件的宿主是一些具有可视化实体的界面元素,而附加事件的宿主是那些不具备显示在界面上的能力,如Binding。附加事件只是路由事件的一种特殊用法,如果在非UIElement中注册了路由事件,事件的激发与监听只能借助其他UIElement元素实现。自定义的附加事件并不常用,最常用的附加事件为Binding的附加事件。

  • 相关阅读:
    Webstorm(OnlineSearch2)自定义快捷搜索API文档手册
    cargo设置国内源
    win10安装rust和编译失败的解决办法
    pycharm打开项目找不到根目录的解决办法
    VM虚拟机/Linux上网
    idea启动springboot项目突然特别慢
    (亲测有效)MacPycharm打不开的解决方法
    vue使用webpack打包失败
    使用七牛云上传文件报错incorrect region, please use up-z1.qiniup.com
    Zookeeper3.5及以上启动时8080端口被占用
  • 原文地址:https://www.cnblogs.com/jefflee/p/5825394.html
Copyright © 2011-2022 走看看