zoukankan      html  css  js  c++  java
  • WPF基础学习笔记整理 (六) RoutedEvent路由事件

    基础知识:

    1. 传统的事件模型中,会在消息触发时将消息通过事件传给事件的订阅者(显式的事件订阅),事件订阅者使用事件处理程序来做出响应。事件订阅者必须能够直接访问到事件的宿主(拥有者)。

    2. 路由事件的事件的拥有者和事件的订阅者之间没有显式订阅关系。拥有者只负责触发事件,它并不知道事件将会由谁响应,事件的订阅者通过事件监听器监听事件,一旦事件触发就对其进行处理(调用相关的事件处理程序),同时并决定该事件是否继续传递。

    3. 传统事件通过.NET事件封装器触发,而路由事件则通过RaiseEvent()方法触发。

    传统事件的参数类型为EventArgs及其子类,而路由事件则是RoutedEventArgs及其子类;


    图1   EventArgs及其子类继承关系

    1. 路由事件使用EventManager.RegisterRoutedEvent()方法注册。
    2. 路由事件同依赖属性一样,也可以共享(通过routedEvent.AddOwner()添加)。
    3. 路由事件出现的三种方式:①直接路由事件(Direct Event),如MouseEnter、②冒泡路由事件(Bubbling Event),如MouseDown和③隧道路由事件(Tunneling Event),如PreviewKeyDown。当注册事件时,会传递一个RoutingStrategy枚举值指定事件行为。
    4. 通过AddHandler()方法可以继续响应被标记为已处理的事件。
    5. 隧道路由事件一般会以单词Preview开发。
    6. Focusable属性定义在UIElement类中。
    7. 自定义路由事件示例:

      WPF代码部分:

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication16"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="WpfApplication16.MainWindow"
            Title="Routed Event" x:Name="window_1" Height="300" Width="300">
        <Grid x:Name="grid_1" local:TimeButton.ReportTime="ReportTimeHandler">
            <Grid x:Name="grid_2" local:TimeButton.ReportTime="ReportTimeHandler">
                <Grid x:Name="grid_3" local:TimeButton.ReportTime="ReportTimeHandler">
                    <StackPanel x:Name="stackPanel_1" local:TimeButton.ReportTime="ReportTimeHandler">
                        <ListBox x:Name="listBox"/>
                        <local:TimeButton x:Name="timeButton" Width="80" Height="80" Content="Telling Time" ReportTime="ReportTimeHandler"/>
                    </StackPanel>
                </Grid>
            </Grid>
        </Grid>
    </Window>
    View Code

    C#代码部分:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication16
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void ReportTimeHandler(object sender, ReportTimeEventArgs e)
            {
                FrameworkElement element = sender as FrameworkElement;
                string timeStr = e.ClickTime.ToLongTimeString();
                string content = string.Format("{0} to {1}", timeStr, element.Name);
                this.listBox.Items.Add(content);
    
                if (element == this.grid_2)
                {
                    e.Handled = true;
                }
            }
        }
    
        class ReportTimeEventArgs : RoutedEventArgs
        {
            public ReportTimeEventArgs(RoutedEvent routedEvent, object source)
                : base(routedEvent, source)
            { }
    
            public DateTime ClickTime { get; set; }
        }
    
        class TimeButton : Button
        {
            public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent("ReportTime", RoutingStrategy.Bubble, typeof(EventHandler<ReportTimeEventArgs>), typeof(TimeButton));
    
            public event RoutedEventHandler ReportTime
            {
                add { this.AddHandler(ReportTimeEvent, value); }
                remove { this.RemoveHandler(ReportTimeEvent, value); }
            }
    
            protected override void OnClick()
            {
                base.OnClick();
    
                ReportTimeEventArgs args = new ReportTimeEventArgs(ReportTimeEvent, this);
                args.ClickTime = DateTime.Now;
                this.RaiseEvent(args);
            }
        }
    }
    View Code

    效果:

    图2  路由事件效果

  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/AmitX-moten/p/4501973.html
Copyright © 2011-2022 走看看