WPF: RoutedEvent

WPF: RoutedEvent

WPF中因为控件都是由其他控件组成的,也就形成了所谓的控件树。所以在事件处理上,与WinForms是不太一样的,它所采用的机制是所谓的RoutedEvent,即事件路由。

注册路由事件时,我们可以选择不同的路由策略。

  • 管道传递(Tunneling): 事件首先在根元素上触发,然后向下层级传递,直到那个最初触发事件的子元素。
  • 冒泡(Bubbling): 事件从最初触发事件的子元素向根元素层级往上传递。
  • 直接(Direct): 事件仅在最初触发事件的子元素上触发。

Window1.xaml

<Window x:Class=”Learn.WPF.Window1″
  xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
  xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
  Title=”Window1″>
  <Grid>
    <Border MouseRightButtonDown=”MouseRightButtonDown”>
      <StackPanel MouseRightButtonDown=”MouseRightButtonDown”>
        <Button MouseRightButtonDown=”MouseRightButtonDown”>Test</Button>
      </StackPanel>
    </Border>
  </Grid>
</Window>

Window1.xaml.cs

public partial class Window1 : Window
{

  public Window1()
  {

    InitializeComponent();
  }
  private void MouseRightButtonDown(object sender, MouseButtonEventArgs e)
  {

    MessageBox.Show((sender as Label).Name);
  }
}

在按钮上单击右键后,你会依次看到显示 “Button”、”StackPanel”、”Border” 的三个对话框,显然事件按照冒泡向根元素传递。
有一点需要注意,WPF 路由事件参数有个 Handled 属性标记,一旦被某个程序标记为已处理,事件传递就会终止。测试一下。

public partial class Window1 : Window
{

  private void MouseRightButtonDown(object sender, MouseButtonEventArgs e)
  {

    MessageBox.Show(sender.GetType().Name);
    if (sender.GetType().Name == “StackPanel”) e.Handled = true;
  }
}

很有效,Border.MouseRightButtonDown 不在有效。严格来说,事件并没有被终止,它依然会继续传递个上级或下级的元素,只是 WPF 没有触发事件代码而已。我们可以使用 AddHandler 方法重新注册一个新的事件处理方法,使得可以继续处理被终止的事件(注意: 如果事件没有终止,这会导致两次事件处理)。

public partial class Window1 : Window
{

  public Window1()
  {

    InitializeComponent();
    this.border1.AddHandler(Border.MouseRightButtonDownEvent,
      new MouseButtonEventHandler(MouseRightButtonDown), true);
  }
  private void MouseRightButtonDown(object sender, MouseButtonEventArgs e)
  {

    MessageBox.Show(sender.GetType().Name);
    if (sender.GetType().Name == “StackPanel”) e.Handled = true;
  }
}

再运行试试,你会发现 Border.MouseRightButtonDown 被触发了。

public void AddHandler(
  RoutedEvent routedEvent,
  Delegate handler,
  bool handledEventsToo
)

handledEventsToo: 如果为 true,则将按以下方式注册处理程序:即使路由事件在其事件数据中标记为已处理,也会调用该处理程序;如果为 false,则使用默认条件注册处理程序,即当路由事件被标记为已处理时,将不调用处理程序。
通常情况下,WPF 控件会在管道事件的名称前添加 Preview 前缀。

<Window x:Class=”Learn.WPF.Window1″
  xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
  xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
  Title=”Window1″>
  <Grid>
    <Border PreviewMouseRightButtonDown=”MouseRightButtonDown”>
      <StackPanel PreviewMouseRightButtonDown=”MouseRightButtonDown”>
        <Button PreviewMouseRightButtonDown=”MouseRightButtonDown”>Test</Button>
      </StackPanel>
    </Border>
  </Grid>
</Window>

这回的输出结果正好跟前面的演示反过来,依次是 “Border”、”StackPanel”、”Button”。如果继续保留事件终止代码,那么 Button.PreviewMouseRightButtonDown 就不再被触发。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110818.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 密宗经典是佛说的吗_华为微信语音加密怎么试听

    密宗经典是佛说的吗_华为微信语音加密怎么试听什么?佛经都能用来加密了?自上次的社会主义核心价值观加密之后,我已经见怪不怪了。题目:夜哆悉諳多苦奢陀奢諦冥神哆盧穆皤三侄三即諸諳即冥迦冥隸數顛耶迦奢若吉怯陀諳怖奢智侄諸若奢數菩奢集遠俱老竟寫明奢若梵等盧皤豆蒙密離怯婆皤礙他哆提哆多缽以南哆心曰姪罰蒙呐神。舍切真怯勝呐得俱沙罰娑是怯遠得呐數罰輸哆遠薩得槃漫夢盧皤亦醯呐娑皤瑟輸諳尼摩罰薩冥大倒參夢侄阿心罰等奢大度地冥殿皤沙蘇輸奢恐豆侄得罰提哆伽諳沙楞缽三死怯摩大蘇者數一遮解析:这题是攻防世界中的一道题目,这一段文字是佛经,按..

    2022年10月23日
  • minicom指令_Minicom 使用初步

    minicom指令_Minicom 使用初步因为现在电脑基本不配备串行接口,所以,usb转串口成为硬件调试时的必然选择。目前知道的,PL2303的驱动是有的,在dev下的名称是ttyUSB#。minicom,tkterm都是linux下应用比较广泛的串口软件,这里简单介绍minicom使用。一,安装debian系,比如ubuntu、mint等:sudoapt-getinstallminicom二,配置首先,查看串口设备是否可用。l…

  • mui的时间控件 picker

    mui的时间控件 pickerhtml,body,.mui-content{height:0px;margin:0px;background-color:#efeff4;}h5.mui-content-padded{margin-left:3px;margin-top:20px!important;}h5.mui-content-padded:first-child

  • cubieboard服务器系统,cubieboard 搭建家用服务器「建议收藏」

    cubieboard服务器系统,cubieboard 搭建家用服务器「建议收藏」犹豫再三,用于买入了cubieboard2。现在用来做家用现在搭配的环境是debain+apache+php+mysql+btsync+xunleilamp是搭建web服务的,btsync是专门用来同步我平板的文件的,平时出去主要用平板来实现过程如下(主要是讲一下大概啊,有问题可以问,尽量解答)系统是debain的,直接刷被人的cubian,感觉还可以。40块入了个二手的80g3.5盘,但是~~…

  • java list最优遍历

    java list最优遍历

  • flume和kafka区别

    flume和kafka区别kafka和flume都是日志系统,kafka是分布式消息中间件,自带存储;flume每一部分都是可以定制。kafka更合适做日志缓存,flume数据采集部分做的很好,可以定制很多数据源,减少开发量。kafka和flume都是日志系统,kafka是分布式消息中间件,自带存储,提供push和pull存取数据功能。flume分为agent(数据采集器),collector(数据简单处理和写入),storage(存储器)三部分,每一部分都是可以定制的。比如agent采用RPC(Thri.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号