zoukankan      html  css  js  c++  java
  • 对WPF事件路由的理解

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace RoutedEvenDemo
    {
        /// <summary>
        /// 对WPF路由事件的理解
        /// </summary>
        public class RoutedEvenDemoTest:UIElement
        {
            public RoutedEvenDemoTest()
            {
                
            }
    
            /*
             1、在.net已经支持事件的情况下,为什么WPF还额外提供了对路由事件的支持?
               WPF中,我们可以将一个控件作为另一个控件的子控件,从而呈现丰富的效果。
               例如我们可以在一个Button中包含一个图像。在这种情况下,对图像的点击实际上应该是对按钮的点击。
               正因为如此,我们期望真正触发被点击事件的控件是Button,而不是嵌在其中的图像。
               这正好要求WPF将点击事件沿视觉树依次传递,即路由事件的路由功能。
               除了这些较为明显的优点之外,路由事件还提供了更为丰富的功能。
               首先,路由事件允许软件开发人员通过EventManager.RegisterClassHandler()函数使用由类定义的静态处理程序。
               这个类定义的静态处理程序与类型的静态构造函数有些类似:在路由事件到达路由中的元素实例时,WPF都会首先调用该类处理程序,
               然后再执行该实例所注册的侦听函数。这种控件编写方式在WPF的内部实现中经常使用。
               另外,通过对路由事件进行管理的类型EventManager,我们可以通过函数调用GetRoutedEvents()得到相应的路由事件,
               而不再需要运用反射等较为耗时的方法。
             2、路由事件一般有哪几种路由策略
               a.冒泡;由事件源向上沿视觉树传递一直到根元素。如 MouseDown
               b.直接;只有事件源才有机会响应事件,某个元素引发事件后,不传递到其他元素
               c.隧道;从元素树的根部调用事件处理程序并依次向下深入直到事件源。
                      一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件。如 PreviewMouseDown
             3、自定义路由事件     
                创建自定义路由事件大体可以分为三个步骤:
    
                (1)声明并注册路由事件 所属注册的类必须派生于 静态制度的 RoutedEvent 
    
                (2)为路由事件添加CLR事件包装 AddHandler 与 RemoveHandler
    
                (3)创建可以激发路由事件的方法
             */
    
    
            public static readonly RoutedEvent testEvent = EventManager.RegisterRoutedEvent("test", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RoutedEvenDemoTest));
    
            public event RoutedEventHandler test
            {
                add { this.AddHandler(testEvent, value); }
                remove { this.RemoveHandler(testEvent, value); }
            }
    
            void testevent()
            {
                RaiseEvent(new RoutedEventArgs(testEvent));
            }
    
            protected override void OnKeyUp(KeyEventArgs e)
            {
                base.OnKeyUp(e);
                testevent();
            }
    
            /// <summary>
            /// 声明注册一个为名称为 DemoTest 的路由事件
            /// </summary>
            public static readonly RoutedEvent DemoTestEvent =
                        EventManager.RegisterRoutedEvent("DemoTest", RoutingStrategy.Bubble, typeof(EventHandler<DemoTestRoutedEventArgs>), typeof(RoutedEvenDemoTest));
    
    
            /// <summary>
            /// CLR事件包装
            /// </summary>
            public event RoutedEventHandler DemoTest
            {
                add { AddHandler(DemoTestEvent, value); }
                remove { RemoveHandler(DemoTestEvent, value); }
            }
    
    
            /// <summary>
            /// 激发路由事件
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                base.OnMouseLeftButtonDown(e);
                DemoTestRoutedEventArgs args = new DemoTestRoutedEventArgs(DemoTestEvent, this);
                args.ClickTime = DateTime.Now;
                this.RaiseEvent(args);
            }
    
            ///// <summary>
            ///// 激发路由事件的方法
            ///// </summary>
            //void DemoEvent()
            //{
            //    RoutedEventArgs args = new RoutedEventArgs(RoutedEvenDemoTest.DemoTestEvent);
            //    RaiseEvent(args);
            //}
    
        }
        
        /// <summary>
        /// 定义一个事件参数类
        /// </summary>
        public class DemoTestRoutedEventArgs : RoutedEventArgs
        {
            public DemoTestRoutedEventArgs(RoutedEvent routedEvent, object source) 
                : base(routedEvent, source)
            {
    
            }
    
            public DateTime ClickTime { get; set; }
        }
    
        /*
         */
    
    }
  • 相关阅读:
    首次远程安装 GlassFish 后以远程 Web 方式访问其后台管理系统出现错误的解决方法(修订)
    在 Mac OS X 环境中从源代码编译安装 FFmpeg
    编译 Android 版本的 Opus 音频编解码库的方法
    在 NetBeans 中开发一般 Java 应用程序时配置 Allatori 进行代码混淆
    使用 IntelliJ IDEA 开发一般 Java 应用程序时配置 Allatori 进行代码混淆
    使用 IntelliJ IDEA 开发 Android 应用程序时配置 Allatori 进行代码混淆
    基于现有图像数据创建自定义像素格式的 BufferedImage
    AppCode 中开发 Mac OS X 应用程序或共享库的经验小结
    MinGW 创建的程序或 DLL 脱离 libgcc-xx-xx.dll 和 libstdc++-x.dll 运行库的方法
    MinGW 使用和创建 DLL 应注意的问题
  • 原文地址:https://www.cnblogs.com/demo8/p/3278669.html
Copyright © 2011-2022 走看看