博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF路由事件学习(一)
阅读量:4585 次
发布时间:2019-06-09

本文共 2941 字,大约阅读时间需要 9 分钟。

路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码(如果用传统的方式实现一个操作,执行过个事件的调用则需要执行代码将事件串连起来方可)

路由事件的路由策略:

所谓的路由策略就是指:路由事件实现遍历元素的方式,总共有三种:

Bubbling(冒泡)

Tunneling(管道传递)

Direct(直接)

一、冒泡:

例:

<Window x:Class="Wpfceshi.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" MouseDown="Window_MouseDown" >
<Grid MouseDown="Grid_MouseDown" x:Name="grid">
<Button Height="30" Width="100" Content="右键点击我" MouseDown="Button_MouseDown"/>
</Grid>
</Window>

using System.Windows;

using System.Windows.Input;
namespace Wpfceshi
{
/// <summary>
/// Window1.xaml 的交互逻辑
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Window被点击");
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Grid被点击");
}
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Button被点击");
}
}
}

 我们会发现当点击button按钮时,button,Grid,window中的事件都会触发,这就是冒泡路由策略的功能所在,事件首先在源元素上触发,然后从每一个元素向上沿着树传递,直到到达根元素为止(或者直到处理程序把事件标记为已处理为止),从而调用这些元素中的路由事件。

事件标记为已处理的情况为:如果把button的事件修改为:

private void Button_MouseDown(object sender, MouseButtonEventArgs e)

        {
            MessageBox.Show("Button被点击");
            e.Handled = true;//这一句可以让事件停止冒泡
        }

则以上事件就不会沿着button-grid-window执行下去,而是只执行button的事件。

如果在以上代码的基础上,还要执行grid 的事件的话,那就需要修改代码:

public Window1()

        {
            InitializeComponent();
            grid.AddHandler(Grid.MouseDownEvent, new RoutedEventHandler(Grid_MouseDown1), true);//等于重新添加了事件
        }

然后添加这个新事件Grid_MouseDown1

private void Grid_MouseDown1(object sender, RoutedEventArgs e)

        {
            MessageBox.Show("Grid被点击");
        }

这样就是冒泡式

二、管道事件:

事件首先是从根元素上被触发,然后从每一个元素向下沿着树传递,直到到达源元素为止(或者直到到达处理程序把事件标记为已处理为止)

 他的执行方式正好与冒泡式的相反。

例子:

还是上面的代码,只需要修改xaml

 <Window x:Class="Wpfceshi.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" PreviewMouseDown="Window_PreviewMouseDown" >
<Grid PreviewMouseDown="Grid_PreviewMouseDown" x:Name="grid">
<Button Height="30" Width="100" Content="点击我" PreviewMouseDown="Button_PreviewMouseDown"/>
</Grid>
</Window>

特别值得注意的是:管道事件按照惯例,他们的名字中都有一个preview前缀,一般来说管道事件都有他的配对的冒泡事件,例如:PreviewMouseDown和MouseDown就是配对事件,如果同时存在的话,那么就会先执行管道事件然后才执行配对的冒泡事件。当然e.Handled=true,依然能够阻断事件。

三、直接:

事件仅仅在源元素上触发,这个与普通的.Net事件的行为相同,不同的是这样的事件仍然会参与一些路由事件的特定机制,如事件触发器等。

该事件唯一可能的处理程序是与其挂接的委托。 

路由事件的事件处理程序的签名:

他与通用的.net事件处理程序的模式一致,也有两个参数:第一个为:System.Object对象,名为sender,第二个参数(一般名为e)是一个派生于System.EventArgs的类。sender参数就是该处理程序被添加的元素,参数e是RoutedEventArgs的一个实例提供了4个有用的属性:

Source---逻辑树中开始触发该事件的的元素。

originalSource--可视树中一开始触发该事件的元素。

handled---布尔值,设置为true表示事件已处理,在这里停止。

RoutedEvent---真正的路由事件对象,(如Button.ClickEvent)当一个事件处理程序同时用于多个路由事件时,它可以有效地识别被出发的事件。

 

转载于:https://www.cnblogs.com/fuchongjundream/p/3836182.html

你可能感兴趣的文章
《代码大全》学习之--使用变量的一般事项
查看>>
JS位操作符
查看>>
mongodb
查看>>
VC++使用socket进行TCP、UDP通信实例总结
查看>>
Docker 构建网络服务后本机不能访问
查看>>
element ui table单选框点击全选问题
查看>>
Prometheus+Grafana监控Kubernetes
查看>>
年假总述
查看>>
BIEE一些目录
查看>>
南阳97
查看>>
【LibreOJ 6278】 数列分块入门 2 (分块)
查看>>
利用Jmeter模拟Github登录
查看>>
解决mybatis空字段null字段不返回
查看>>
生命的意义
查看>>
Box-Muller 与 ziggurat
查看>>
zookeeper+dubbo问题
查看>>
dubbo zookeeper图解入门配置
查看>>
winform如何不卡界面
查看>>
Random随机库
查看>>
AFNetworking 3.0x版本最新特性
查看>>