《WPF程序设计指南》读书笔记——第9章 路由输入事件_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 《WPF程序设计指南》读书笔记——第9章 路由输入事件

《WPF程序设计指南》读书笔记——第9章 路由输入事件

 2013/9/7 21:11:43  小p  博客园  我要评论(0)
  • 摘要:1.路由事件的作用路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。通俗地说,路由事件会在可视树(逻辑树是其子集)上,上下routed,如果哪个节点上订阅了事件,就会被触发。路由事件的规则有三种:(1)冒泡;由事件源向上沿视觉树传递一直到根元素。如MouseDown(2)直接;只有事件源才有机会响应事件,某个元素引发事件后,不传递到其他元素(3)隧道;从元素树的根部调用事件处理程序并依次向下深入直到事件源。一般情况下
  • 标签:事件 程序 笔记 读书笔记 设计

1.路由事件的作用

    路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。通俗地说,路由事件会在可视树(逻辑树是其子集)上,上下routed,如果哪个节点上订阅了事件,就会被触发。

    路由事件的规则有三种:

    (1)冒泡;由事件源向上沿视觉树传递一直到根元素。如 MouseDown

    (2)直接;只有事件源才有机会响应事件,某个元素引发事件后,不传递到其他元素

    (3)隧道;从元素树的根部调用事件处理程序并依次向下深入直到事件源。 一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件。如 PreviewMouseDown

    可以通过 e.handled = true 来停止路由。

class="brush:csharp;collapse:true;;gutter:true;">using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Documents;

namespace LY.ExamineRoutedEvents
{
    public class ExamineRoutedEvents : Application
    {
        static readonly FontFamily fontfam = new FontFamily("宋体");
        const string strformat = "{0,-30},{1,-15},{2,-15},{3,-15}";
        StackPanel stackOutput;
        DateTime dtLast;
        [STAThread]
        public static void Main()
        {
            ExamineRoutedEvents app = new ExamineRoutedEvents();
            app.Run();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Window win = new Window();
            win.Title = "Examine Routed Events";
            //建立Grid
            Grid grid = new Grid();
            win.Content = grid;
            //建立三行
            RowDefinition rowdef = new RowDefinition();
            rowdef.Height = GridLength.Auto;
            grid.RowDefinitions.Add(rowdef);

            rowdef = new RowDefinition();
            rowdef.Height = GridLength.Auto;
            grid.RowDefinitions.Add(rowdef);

            rowdef = new RowDefinition();
            rowdef.Height = new GridLength(100, GridUnitType.Star);
            grid.RowDefinitions.Add(rowdef);

            //建立button,加入到grid
            Button btn = new Button();
            btn.HorizontalAlignment = HorizontalAlignment.Center;
            btn.Padding = new Thickness(24);
            btn.Margin = new Thickness(24);
            grid.Children.Add(btn);
            //建立textblock,加入button
            TextBlock text = new TextBlock();
            text.FontSize = 24;
            text.Text = win.Title;
            btn.Content = text;
            //建立标题,显示在ScrollViewer
            TextBlock textHeadings = new TextBlock();
            textHeadings.FontFamily = fontfam;
            textHeadings.Inlines.Add(new Underline(new Run(string.Format(strformat,
                "Routed Events", "Sender", "Source", "OriginalSource"))));
            grid.Children.Add(textHeadings);
            Grid.SetRow(textHeadings, 1);
            //加入Scorllviewer
            ScrollViewer scroll = new ScrollViewer();
            grid.Children.Add(scroll);
            Grid.SetRow(scroll, 2);
            //建立Stackpanel,放入Scorllviewer
            stackOutput = new StackPanel();
            scroll.Content = stackOutput;
            //新增事件处理器
            UIElement[] els = { win, grid, btn, text };
            foreach (UIElement el in els)
            {
                // Keyboard
                el.PreviewKeyDown += AllPurposeEventHandler;
                el.PreviewKeyUp += AllPurposeEventHandler;
                el.PreviewTextInput += AllPurposeEventHandler;
                el.KeyDown += AllPurposeEventHandler;
                el.KeyUp += AllPurposeEventHandler;
                el.TextInput += AllPurposeEventHandler;

                // Mouse
                el.MouseDown += AllPurposeEventHandler;
                el.MouseUp += AllPurposeEventHandler;
                el.PreviewMouseDown += AllPurposeEventHandler;
                el.PreviewMouseUp += AllPurposeEventHandler;
                
                // Stylus
                el.StylusDown += AllPurposeEventHandler;
                el.StylusUp += AllPurposeEventHandler;
                el.PreviewStylusDown += AllPurposeEventHandler;
                el.PreviewStylusUp += AllPurposeEventHandler;
                //Window,Grid,Textblock类没有click事件,所以用在ButtonBase类中定义的AddHandler方法
                el.AddHandler(Button.ClickEvent,
                    new RoutedEventHandler(AllPurposeEventHandler));               
            }
            win.Show();
        }

        void AllPurposeEventHandler(object sender, RoutedEventArgs e)
        {
            //如果有时间空隙,加入空格
            DateTime dtNow = DateTime.Now;
            if (dtNow - dtLast > TimeSpan.FromMilliseconds(100))
                stackOutput.Children.Add(new TextBlock(new Run()));
            dtLast = dtNow;
            //显示事件信息
            TextBlock text = new TextBlock();
            text.FontFamily = fontfam;
            text.Text = string.Format(strformat, e.RoutedEvent.Name,
                TypeWithoutNamespace(sender), 
                TypeWithoutNamespace(e.Source),
                TypeWithoutNamespace(e.OriginalSource));
            stackOutput.Children.Add(text);
            (stackOutput.Parent as ScrollViewer).ScrollToBottom();
        }
        string TypeWithoutNamespace(object obj)
        {
            string[] str = obj.GetType().ToString().Split('.');
            return str[str.Length-1];
        }
    }
}

 2.自定义路由事件

 

发表评论
用户名: 匿名