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 就不再被触发。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • varchar2 类型「建议收藏」

    varchar2 类型「建议收藏」1、varchar2在数据库表中的最大长度是4000bytesorcharacter,在oracleplsqlvarchar2最大支持长度为32767个字节SQL>declare 2       v_varvarchar2(32767); 3     begin 4       null; 5     end; 6     /

    2022年6月24日
    33
  • maven配置环境变量失败解决办法

    maven配置环境变量失败解决办法配置maven路径什么的统统正确,最后测hi不成功。在网上搜索了好多资料方法都解不了具体问题具体对待吧,如果有和我类似的小伙伴,可以尝试一下我的这个办法,在maven路径后面加/binpath变量中测试输入mva-v(中间有个空格)成功!如果还是不能解决也可以参这个https://blog.csdn.net/xudaliang_…

    2022年7月25日
    22
  • linux 文件锁

    linux 文件锁1.文件锁基本概念Linux中软件、硬件资源都是文件(一切皆文件),文件在多用户环境中是可共享的。文件锁是用于解决资源的共享使用的一种机制:当多个用户需要共享一个文件时,Linux通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。文件锁包括建议性锁和强制性锁:建议性锁:要求每个使用上锁文件的进程都要检查是否有锁存在,并且尊重已有的锁。在一般情况下,内核和系统都不使用建议性锁,它们依靠程序员遵守这个规定。强制性锁:是由内核执行的锁,当一个文件被上锁进行写入操作的时候,内核将阻止其他任何

    2022年6月28日
    37
  • spring boot + kafka 使用详细步骤[通俗易懂]

    spring boot + kafka 使用详细步骤[通俗易懂]一,Kafka的安装以及配置1.下载文件wgethttp://mirror.bit.edu.cn/apache/kafka/0.11.0.0/kafka_2.11-0.11.0.0.tgz2.安装tarxzvfkafka_2.11-0.11.0.0.tgz-C/usr/local/3.配置(服务器在阿里云ECS上)vi%kafka_home%/server…

    2022年5月9日
    141
  • mysql学习之mysql集群

    mysql学习之mysql集群本片博文是笔者学习《高性能mysql》一书的第一篇学习笔记,对应书籍章节为第10章。主要介绍了mysql集群部署方案主从集群部署。集群方案、主从同步原理、复制类型、docker安装mysql集群示例。

    2025年8月13日
    3
  • Swoole的多进程模块[通俗易懂]

    Swoole的多进程模块

    2022年2月11日
    52

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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