這次學到的是 WPF 的 EventRouting
有一個 Window,xaml 如下
<Window x:Class="WpfApplication1.MainForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainForm" Height="300" Width="300" >
<Grid>
<StackPanel Name="MyPanel"></StackPanel>
</Grid>
</Window>
而 code 如下。
public MainForm()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
var button = new Button() {Content = "Button " + i};
MyPanel.Children.Add(button);
button.Click += new RoutedEventHandler(button_Click);
}
}
void button_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
MessageBox.Show(button.Content.ToString());
}
執行時,會產生5個 button。每一個 button 被Click 後,會拋出所click 的按鍵訊息。
這樣的寫作方式與以前的 windows form 並沒有什麼兩樣。每個 button 的 click event 都註冊了相同的 event handler,似乎有點笨。
Event Bubbling
由於 event bubbling 的關係,button 的也會傳到其 Parent Container,在這個例子是名為 MyPanel 的 StackPanel。因此理論上MyPanel 可以收的到 Click Event.
問題來了,StackPanel 並沒有 Click Event,因此無法註冊 EventHandler. 如下圖。
RountEvent
雖然 MyPanel 無法直接註冊 Click Event, 但在 WPF 中由於 DependecyProperty 的幫助,我們可以使用 MyPanel.AddHandler方法的協助來註冊 Button 的 Click Event 的 Event Handler
public MainForm()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
var button = new Button() {Content = "Button " + i};
MyPanel.Children.Add(button);
//button.Click += new RoutedEventHandler(button_Click);
}
MyPanel.AddHandler(Button.ClickEvent, new RoutedEventHandler(button_Click));
}
void button_Click(object sender, RoutedEventArgs e)
{
var button = e.Source as Button; //我也改了這一行
MessageBox.Show(button.Content.ToString());
}
注意到我改了 e.Source。e.Source 是指真正發生 Event 的物件,即 Button。而sender 會指到 MyPanel,並不是我們想要的。
沒有留言:
張貼留言