2009年9月17日 星期四

在WPF中滑鼠事件(Mouse Event)傳遞

WPF和.net form的一個很大的差異就是
大部分的控制項都已經沒有Click(除了按鈕(Button)之外)
猜測大概是因為希望未來在觸控(Touch)的世界裡面可以順利接軌吧

另外,不像.net form裡面,只有最表面(可視)的部分才能接收到事件
針對幾乎所有的事件(Event)都有Preview的機制
也就是說在上層(Parent)先收到Preview,然後傳遞到下層(Child)
等到沒有下層,或是已經引發了事件發生的話再作回傳
然後由下層先引發真正的事件,再繼續回傳

舉例來說,如果有一個架構如下

<Window ... Name="Win">
<Grid Name="Grd">
<Rectangle Name="Rec" />
</Grid>
</Window>

而我們觀察的滑鼠事件如下
事件
PreviewMouseLeftButtonDown
PreviewMouseDown
PreviewMouseLeftButtonUp
PreviewMouseUp
MouseLeftButtonDown
MouseDown
MouseLeftButtonUp
MouseUp
Click

將想要觀察的滑鼠事件都加上相同的事件處理

private void MouseEH(object sender, RoutedEventArgs e)
{
Console.WriteLine(
(sender as FrameworkElement).Name + " : " +
e.RoutedEvent.Name);
}

因為這邊用到Console,所以要特別去設定為Console的模式
在工具列中找到專案->屬性

然後設定應用程式->輸出類型,選擇"主控台應用程式"

然後在按鈕中間的方塊按下去,會得到下面的結果

Win : PreviewMouseLeftButtonDown
Win : PreviewMouseDown
Grd : PreviewMouseLeftButtonDown
Grd : PreviewMouseDown
Rec : PreviewMouseLeftButtonDown
Rec : PreviewMouseDown
Rec : MouseLeftButtonDown
Rec : MouseDown
Grd : MouseLeftButtonDown
Grd : MouseDown
Win : MouseLeftButtonDown
Win : MouseDown
Win : PreviewMouseLeftButtonUp
Win : PreviewMouseUp
Grd : PreviewMouseLeftButtonUp
Grd : PreviewMouseUp
Rec : PreviewMouseLeftButtonUp
Rec : PreviewMouseUp
Rec : MouseLeftButtonUp
Rec : MouseUp
Grd : MouseLeftButtonUp
Grd : MouseUp
Win : MouseLeftButtonUp
Win : MouseUp

從這個例子可以看出最簡單的WPF滑鼠事件傳遞順序
更複雜的例子可以參考按鈕(Button)篇以及列表框(ListBox)篇

--
參考資料
WPF的Event

沒有留言:

張貼留言