路由事件的傳播方式
通過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();
}
}
}