這次學到的是 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,並不是我們想要的。
沒有留言:
張貼留言