WPF学习02:Routed Events
與傳統的桌面開發相比,在事件模型上WPF引入了Routed Events,從開發者的角度上,我們獲得了兩個便利:
1.可以實現事件路由,即向XAML結構中的父元素路由或者是向子元素路由。
2. RoutedEventArgs作為默認的事件Args為我們提供了更多的信息。
事件應用示例
建立工程“RoutedEvent”,初始的代碼修改Grid Layout為StackPanel,添加了一個Button,如下圖:
編寫Click Event Handler:
private void ButtonA_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Get it");
}
我們有兩種方式為該按鈕添加Click Event Handler:
XAML形式:
<Button Name="ButtonA" Click="ButtonA_Click">ButtonA</Button>
C#形式:
ButtonA.AddHandler(Button.ClickEvent, new RoutedEventHandler(ButtonA_Click)); ButtonA.Click += ButtonA_Click; //這樣亦可,但只能用于該控件支持的事件
結果:
注意:一個事件,同一個handler添加多次的結果如下圖,是引發Bug的誘因之一:
RoutedEventArgs
從上一個例子我們可以看到,WPF事件機制默認提供的EventArgs為RoutedEventArgs
public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);
與EventArgs相比,Routed Event提供了4個新的屬性.
RoutedEvent:可以獲取到時間的類型,可以在一個Handler處理多個不同類型事件時用上。
其它三個都與事件路由相關:
Handled,指定sender是否對該事件繼續路由,接下來的例子會展示它的作用。
Source,該事件的觸發源。
OriginalSource,通常與Source為同一個值。
事件路由
以事件路由模式來分類,WPF提供了3種事件路由模式:
Direct (不路由)
Bubbling events(向上路由)
Tunneling events(向下路由)
對于一個事件,如果不清楚它的路由模式,可以MSDN查一下:比如:MSDN上關于Click的說明:
直接以例子來說明事件路由的作用:我們修改一下XAML代碼,如下:
<StackPanel>
<Button Name="ButtonA">ButtonA</Button>
<Button Name="ButtonB">ButtonB</Button>
<Button Name="ButtonC">ButtonC</Button>
<Button Name="ButtonD">ButtonD</Button>
<Button Name="ButtonE">ButtonE</Button>
<Button Name="ButtonF">ButtonF</Button>
<Button Name="ButtonG">ButtonG</Button>
<Button Name="ButtonH">ButtonH</Button>
</StackPanel>
現在界面上有了8個Button,如果需要為8個按鈕都做事件處理,那要怎么做呢?通過事件路由我們可以很優雅的解決:
由于Click為向上路由的事件,我們隨便找它的一個父元素,比如stackPanel,填加一句代碼就好了:
<StackPanel Button.Click="Button_Click">
以下為Handler代碼:
private void Button_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Get Info From {0}", e.Source);
}
結果:
為頂層Window添加同樣的代碼會得到相同的結果,因為事件將一直路由到頂層。
最后,回顧一下剛才RoutedEventArgs中的Handled.
接下來的例子說明了如何通過設置Handled阻礙事件路由:
XAML代碼:
<Window x:Class="RoutedEvent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Button.Click="Button_Click">
<StackPanel Name="StackPanelA">
<Button Name="ButtonA">ButtonA</Button>
<Button Name="ButtonB">ButtonB</Button>
<Button Name="ButtonC">ButtonC</Button>
<Button Name="ButtonD">ButtonD</Button>
<Button Name="ButtonE">ButtonE</Button>
<Button Name="ButtonF">ButtonF</Button>
<Button Name="ButtonG">ButtonG</Button>
<Button Name="ButtonH">ButtonH</Button>
</StackPanel>
</Window>
C#代碼:
public MainWindow()
{
InitializeComponent();
StackPanelA.AddHandler(Button.ClickEvent, new RoutedEventHandler(StackPanel_Click), true);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Get Info From {0}", e.Source);
}
private void StackPanel_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("I will block the routing", e.Source);
e.Handled = true;
}
結果:事件路由將到了StackPanel即被阻礙,Window的對于Click 的Handler將不會觸發,大家可以試試。
總結
以上是生活随笔為你收集整理的WPF学习02:Routed Events的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hevc/265 开源项目及相关
- 下一篇: Android Button字母自动全部