路由事件的传播方式
通过RoutingStrategy来定义传播的方式
public enum RoutingStrategy
{
Tunnel = 0, //隧道,由顶层元素向内传播,事件一般以Preview开头 (由最外层向内传播)
Bubble = 1, //冒泡,与隧道相反,向外传播 (由内向外传播)
Direct = 2, //直接,与传统的事件相似
}
WPF中的路由事件用的最多的就是Tunnel和Bubble这两种传播方式,所以一般路由事件都是成对出现,
如:PreviewMouseLeftDown和MouseLeftDown
注意:Tunnel事件总是比Bubble事件先执行,如果在Tunnel事件中设置了Handled = true,那么成对的Bubble事件将不会发生,因为它们共享同一个RoutedEventArgs类的实例,在转播的过程中设置了Handled = true, 路由事件还是会继续传播,只是不会执行。
看一个例子:以下控件都设置了冒泡事件MouseUp,点击最上面label 事件有 label向上传递到window
BubbledLabelClick.xaml
<Window x:Class="RoutedEvents.BubbledLabelClick"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BubbledLabelClick" Height="359" Width="329"
MouseUp="SomethingClicked"
>
<Grid Margin="3" MouseUp="SomethingClicked">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" MouseUp="SomethingClicked" HorizontalAlignment="Left" >
<StackPanel MouseUp="SomethingClicked" >
<TextBlock Margin="3" MouseUp="SomethingClicked" >
Image and picture label</TextBlock>
<Image Source="happyface.jpg" Stretch="None"
MouseUp="SomethingClicked" />
<TextBlock Margin="3"
MouseUp="SomethingClicked" >
Courtesy of the StackPanel</TextBlock>
</StackPanel>
</Label>
<ListBox Margin="5" Name="lstMessages" Grid.Row="1"></ListBox>
<CheckBox Margin="5" Grid.Row="2" Name="chkHandle">Handle first event</CheckBox>
<Button Click="cmdClear_Click" Grid.Row="3" HorizontalAlignment="Right" Margin="5" Padding="3">Clear List</Button>
</Grid>
</Window>
BubbledLabelClick.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace RoutedEvents
{
/// <summary>
/// Interaction logic for RoutedLabelClick.xaml
/// </summary>
public partial class BubbledLabelClick : System.Windows.Window
{
public BubbledLabelClick()
{
InitializeComponent();
}
protected int eventCounter = 0;
private void SomethingClicked(object sender, RoutedEventArgs e)
{
eventCounter++;
string message = "#" + eventCounter.ToString() + ":\r\n" +
" Sender: " + sender.ToString() + "\r\n" +
" Source: " + e.Source + "\r\n" +
" Original Source: " + e.OriginalSource;
lstMessages.Items.Add(message);
e.Handled = (bool)chkHandle.IsChecked;//设置Handled=true之后事件就不在传递
}
private void cmdClear_Click(object sender, RoutedEventArgs e)
{
eventCounter = 0;
lstMessages.Items.Clear();
}
}
}