zoukankan      html  css  js  c++  java
  • WPF路由事件

    逻辑树

    <Window>
      <Grid>
        <Button>
          <StackPanel>
            <Image/>
            <TextBlock/>
          </StackPanel>
        </Button>
      </Grid>
    </Window>

    但是实际上这些元素在运行时会扩展为可是树

    image
     

    事件路由

    对逻辑树和可视树有所了解很有必要,因为路由事件主要是根据可视树进行路由。路由事件支持三种路由策略:气泡、隧道和直接。

    气泡事件最为常见,它表示事件从源元素扩散(传播)到可视树,直到它被处理或到达根元素。这样您就可以针对源元素的上方层级对象处理事件。例如,您可向嵌入的 Grid 元素附加一个 Button.Click 处理程序,而不是直接将其附加到按钮本身。气泡事件有指示其操作的名称(例如,MouseDown)。

    隧道事件采用另一种方式,从根元素开始,向下遍历元素树,直到被处理或到达事件的源元素。这样上游元素就可以在事件到达源元素之前先行截取并进行处理。根据命名惯例,隧道事件带有前缀 Preview(例如 PreviewMouseDown)。

    直接事件类似 .NET Framework 中的正常事件。该事件唯一可能的处理程序是与其挂接的委托。

    通常,如果为特殊事件定义了隧道事件,就会有相应的气泡事件。在这种情况下,隧道事件先触发,从根元素开始,下行至源元素,查找处理程序。一旦它被处理或到达源元素,即会触发气泡事件,从源元素上行,查找处理程序。气泡或隧道事件不会仅因调用事件处理程序而停止路由。如果您想中止隧道或气泡进程,可使用您传递的事件参数在事件处理程序中将事件标记为已处理。

    示例(我们在Grid上加了一个Button.Click的附加事件:

    01 <Window x:Class="DeepXAML.MainWindow"
    03         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    04         xmlns:local="clr-namespace:DeepXAML"       
    05         xmlns:sys="clr-namespace:System;assembly=mscorlib"
    06         Title="MainWindow" Height="250" Width="450">
    07     <Grid x:Name="rootGrid" Button.Click="rootGrid_Click">
    08         <Button x:Name="btnOK" Margin="30">OK</Button>
    09     </Grid>
    10 </Window>

    后台代码:

    1 private void rootGrid_Click(object sender, RoutedEventArgs e)
    2 {
    3     MessageBox.Show((e.Source as FrameworkElement).Name); //btnOk
    4     MessageBox.Show((e.OriginalSource as FrameworkElement).Name); //btnOk
    5 }

    source是指LogicTree的源途,orginalSource指的是VisualTree上的源

    自定义路由事件示例

    01 <Window x:Class="DeepXAML.MainWindow"
    03         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    04         xmlns:local="clr-namespace:DeepXAML"       
    05         xmlns:sys="clr-namespace:System;assembly=mscorlib"
    06         Title="MainWindow" Height="250" Width="450">
    07     <Grid x:Name="rootGrid" >
    08         <StackPanel x:Name="stp1" local:TestButton.ClickTimeEvent="TimeHanler">
    09             <StackPanel x:Name="stp2" local:TestButton.ClickTimeEvent="TimeHanler">
    10                 <StackPanel x:Name="stp3" local:TestButton.ClickTimeEvent="TimeHanler">
    11                     <ListBox x:Name="listBox"></ListBox>
    12                     <local:TestButton local:TestButton.ClickTimeEvent="TimeHanler" Height="50" Margin="30">OK</local:TestButton>
    13                 </StackPanel>
    14             </StackPanel>
    15         </StackPanel>       
    16     </Grid>
    17 </Window>
    1 后台代码
    01 using System;
    02 using System.Collections.Generic;
    03 using System.Windows;
    04 using System.Windows.Data;
    05 using System.Windows.Documents;
    06 using System.Windows.Controls;
    07   
    08 namespace DeepXAML
    09 {
    10     public partial class MainWindow : Window
    11     {
    12         public MainWindow()
    13         {
    14             InitializeComponent();
    15       
    16         }
    17   
    18         private void TimeHanler(object sender, TimeEventArgs e)
    19         {
    20             FrameworkElement element = sender as FrameworkElement;
    21             string strTime = e.ClickTime.ToLongTimeString();
    22             this.listBox.Items.Add( element.Name+":"+ strTime);
    23         }              
    24     }
    25   
    26     public class TimeEventArgs : RoutedEventArgs
    27     {
    28         public TimeEventArgs(RoutedEvent routedEvent, object source):base(routedEvent,source)
    29         {           
    30         }
    31         public DateTime ClickTime { get; set; }
    32     }
    33   
    34     public class TestButton : Button
    35     
    36       public static RoutedEvent timeEvent=
    37           EventManager.RegisterRoutedEvent("ClickTimeEvent", RoutingStrategy.Bubble, typeof(EventHandler<TimeEventArgs>), typeof(TestButton));
    38   
    39         public event  RoutedEventHandler ClickTimeEvent
    40         {
    41           add {this.AddHandler(timeEvent,value);}
    42           remove{this.RemoveHandler(timeEvent,value);}
    43         }
    44   
    45         protected override void  OnClick()
    46         {
    47               base.OnClick();
    48             TimeEventArgs args=new TimeEventArgs(timeEvent,this);
    49             args.ClickTime=DateTime.UtcNow;
    50             this.RaiseEvent(args);
    51         }
    52     }    
    53 }
  • 相关阅读:
    巴比伦富翁的理财课:有史以来最完美的致富圣经读后感
    【数据结构与算法】爱吃香蕉的珂珂:二分法思想实现
    【数据结构与算法】有序数组查找:二分查找算法实现
    【数据结构与算法】找出最小的k个数:三路快速排序算法思想实现
    【数据结构与算法】第K大的元素:三路快速排序算法思路
    【数据结构与算法】颜色分类:三路快速排序算法思想实现
    页面轮播
    sh重启脚本
    关于mac自带的openssl和brew安装的openssl冲突
    vconsole使用
  • 原文地址:https://www.cnblogs.com/luluping/p/2039491.html
Copyright © 2011-2022 走看看