zoukankan      html  css  js  c++  java
  • WPF学习02:Routed Events

      与传统的桌面开发相比,在事件模型上WPF引入了Routed Events,从开发者的角度上,我们获得了两个便利:

      1.可以实现事件路由,即向XAML结构中的父元素路由或者是向子元素路由。

          2. RoutedEventArgs作为默认的事件Args为我们提供了更多的信息。

    事件应用示例

      建立工程“RoutedEvent”,初始的代码修改Grid Layout为StackPanel,添加了一个Button,如下图:

       

      编写Click Event Handler:

     private void ButtonA_Click(object sender, RoutedEventArgs e)
     {
         System.Diagnostics.Debug.WriteLine("Get it");
     }

       我们有两种方式为该按钮添加Click Event Handler:

      XAML形式:

     <Button Name="ButtonA" Click="ButtonA_Click">ButtonA</Button>

       C#形式:

     ButtonA.AddHandler(Button.ClickEvent, new RoutedEventHandler(ButtonA_Click)); 
     ButtonA.Click += ButtonA_Click;  //这样亦可,但只能用于该控件支持的事件

      结果:

      

      注意:一个事件,同一个handler添加多次的结果如下图,是引发Bug的诱因之一:

      

      

    RoutedEventArgs

      从上一个例子我们可以看到,WPF事件机制默认提供的EventArgs为RoutedEventArgs

     public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);

      与EventArgs相比,Routed Event提供了4个新的属性.

      RoutedEvent:可以获取到时间的类型,可以在一个Handler处理多个不同类型事件时用上。

      其它三个都与事件路由相关:

      Handled,指定sender是否对该事件继续路由,接下来的例子会展示它的作用。

      Source,该事件的触发源。

      OriginalSource,通常与Source为同一个值。

      

    事件路由

      以事件路由模式来分类,WPF提供了3种事件路由模式:

    1. Direct (不路由)
    2. Bubbling events(向上路由)
    3. Tunneling events(向下路由)

      对于一个事件,如果不清楚它的路由模式,可以MSDN查一下:比如:MSDN上关于Click的说明:

      

      直接以例子来说明事件路由的作用:我们修改一下XAML代码,如下:

     <StackPanel>
            <Button Name="ButtonA">ButtonA</Button>
            <Button Name="ButtonB">ButtonB</Button>
            <Button Name="ButtonC">ButtonC</Button>
            <Button Name="ButtonD">ButtonD</Button>
            <Button Name="ButtonE">ButtonE</Button>
            <Button Name="ButtonF">ButtonF</Button>
            <Button Name="ButtonG">ButtonG</Button>
            <Button Name="ButtonH">ButtonH</Button>
     </StackPanel>

      现在界面上有了8个Button,如果需要为8个按钮都做事件处理,那要怎么做呢?通过事件路由我们可以很优雅的解决:

      由于Click为向上路由的事件,我们随便找它的一个父元素,比如stackPanel,填加一句代码就好了:

     <StackPanel Button.Click="Button_Click">

      以下为Handler代码:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Get Info From {0}", e.Source);
    }

      结果:

      

      为顶层Window添加同样的代码会得到相同的结果,因为事件将一直路由到顶层。

      最后,回顾一下刚才RoutedEventArgs中的Handled.

      接下来的例子说明了如何通过设置Handled阻碍事件路由:

      XAML代码:

     <Window x:Class="RoutedEvent.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Button.Click="Button_Click">
        <StackPanel Name="StackPanelA">
            <Button Name="ButtonA">ButtonA</Button>
            <Button Name="ButtonB">ButtonB</Button>
            <Button Name="ButtonC">ButtonC</Button>
            <Button Name="ButtonD">ButtonD</Button>
            <Button Name="ButtonE">ButtonE</Button>
            <Button Name="ButtonF">ButtonF</Button>
            <Button Name="ButtonG">ButtonG</Button>
            <Button Name="ButtonH">ButtonH</Button>
        </StackPanel>
     </Window>

      C#代码:

      

     public MainWindow()
     {
         InitializeComponent();
         StackPanelA.AddHandler(Button.ClickEvent, new RoutedEventHandler(StackPanel_Click), true);
     }
            
     private void Button_Click(object sender, RoutedEventArgs e)
     {
         System.Diagnostics.Debug.WriteLine("Get Info From {0}", e.Source);
     }
    
     private void StackPanel_Click(object sender, RoutedEventArgs e)
     {
        System.Diagnostics.Debug.WriteLine("I will block the routing", e.Source);
        e.Handled = true;
     }

      结果:事件路由将到了StackPanel即被阻碍,Window的对于Click 的Handler将不会触发,大家可以试试。

  • 相关阅读:
    flutter 和 NTFS
    APIO2020 游记
    CF1336F Journey
    ZJOI2020 游记
    CF568E Longest Increasing Subsequence
    CSP2020 游记
    洛谷 P6217 简单数论题
    CF587F Duff is Mad
    CF526G Spiders Evil Plan
    WC2021 游记
  • 原文地址:https://www.cnblogs.com/E-WALKER/p/4371992.html
Copyright © 2011-2022 走看看