MouseLeftButtonDown 是冒泡事件,从下往根节点传递;PreviewMouseLeftButtonDown 是隧道事件,从根节点往下传递,所以换成PreviewMouseLeftButtonDown。
1. 点击事件的执行顺序
- PreviewMouseLeftButtonDown
- PreviewMouseDown
- MouseLeftButtonDown
- MouseDown
- PreviewMouseLeftButtonUp
- PreviewMouseUp
- Click
- MouseLeftButtonUp
- MouseUp
1)PreviewMouseLeftButtonDown 是隧道事件,从根节点往下传递
2)MouseLeftButtonDown 是冒泡事件,从下往根节点传递
3)知道这两点,再来看前面从 PreviewMouseLeftButtonDown 到 MouseUp 的整个过程及 Click 在当中所处的顺序,就好理解很多
4)具体:
鼠标即将点下,从根节点往下传递
->控件接受到鼠标点下,从下往根节点冒泡
->鼠标即将弹起,从上往下传递
->控件接受到鼠标要松开,若是 ButtonBase 等有 Click 事件的控件则触发 Click 事件
->控件从下往上冒泡鼠标弹起事件。
2.例子
<StackPanel x:Name="s0" Height="100" Width="200" Background="Red"
PreviewMouseLeftButtonDown="PreviewMouseLeftButtonDownEventHandler"
PreviewMouseDown="PreviewMouseDownEventHandler"
MouseLeftButtonDown="MouseLeftButtonDownEventHandler"
MouseDown="MouseDownEventHandler"
PreviewMouseLeftButtonUp="PreviewMouseLeftButtonUpEventHandler"
PreviewMouseUp="PreviewMouseUpEventHandler"
MouseLeftButtonUp="MouseLeftButtonUpEventHandler"
MouseUp="MouseUpEventHandler">
<StackPanel x:Name="s1" Height="90" Width="180" Background="Yellow"
PreviewMouseLeftButtonDown="PreviewMouseLeftButtonDownEventHandler"
PreviewMouseDown="PreviewMouseDownEventHandler"
MouseLeftButtonDown="MouseLeftButtonDownEventHandler"
MouseDown="MouseDownEventHandler"
PreviewMouseLeftButtonUp="PreviewMouseLeftButtonUpEventHandler"
PreviewMouseUp="PreviewMouseUpEventHandler"
MouseLeftButtonUp="MouseLeftButtonUpEventHandler"
MouseUp="MouseUpEventHandler">
<Button x:Name="btn" Height="40" Width="78" Content="click"
Click="Button_ClickEventHandler"
MouseLeftButtonDown="MouseLeftButtonDownEventHandler"
PreviewMouseLeftButtonDown="PreviewMouseLeftButtonDownEventHandler"
PreviewMouseDown="PreviewMouseDownEventHandler"
MouseDown="MouseDownEventHandler"
PreviewMouseLeftButtonUp="PreviewMouseLeftButtonUpEventHandler"
PreviewMouseUp="PreviewMouseUpEventHandler"
MouseLeftButtonUp="MouseLeftButtonUpEventHandler"
MouseUp="MouseUpEventHandler">
</Button>
</StackPanel>
</StackPanel>
2.1 方法
private void PrintControlAndEvent(string controlName, string routedEventName)
{
Console.WriteLine(string.Format("{0} : {1}", controlName, routedEventName));
}
private void PreviewMouseLeftButtonDownEventHandler(object sender, MouseButtonEventArgs e)
{
PrintControlAndEvent((sender as FrameworkElement).Name, e.RoutedEvent.ToString());
}
...
private void Button_ClickEventHandler(object sender, RoutedEventArgs e)
{
PrintControlAndEvent((sender as FrameworkElement).Name, e.RoutedEvent.ToString());
}
2.2 输出
2.2.1点击 Button
s0 : UIElement.PreviewMouseLeftButtonDown
s0 : Mouse.PreviewMouseDown
s1 : UIElement.PreviewMouseLeftButtonDown
s1 : Mouse.PreviewMouseDown
btn : UIElement.PreviewMouseLeftButtonDown
btn : Mouse.PreviewMouseDown
s0 : UIElement.PreviewMouseLeftButtonUp
s0 : Mouse.PreviewMouseUp
s1 : UIElement.PreviewMouseLeftButtonUp
s1 : Mouse.PreviewMouseUp
btn : UIElement.PreviewMouseLeftButtonUp
btn : Mouse.PreviewMouseUp
btn : ButtonBase.Click
2.2.2 点击s1
s0 : UIElement.PreviewMouseLeftButtonDown
s0 : Mouse.PreviewMouseDown
s1 : UIElement.PreviewMouseLeftButtonDown
s1 : Mouse.PreviewMouseDown
s1 : UIElement.MouseLeftButtonDown
s1 : Mouse.MouseDown
s0 : UIElement.MouseLeftButtonDown
s0 : Mouse.MouseDown
s0 : UIElement.PreviewMouseLeftButtonUp
s0 : Mouse.PreviewMouseUp
s1 : UIElement.PreviewMouseLeftButtonUp
s1 : Mouse.PreviewMouseUp
s1 : UIElement.MouseLeftButtonUp
s1 : Mouse.MouseUp
s0 : UIElement.MouseLeftButtonUp
s0 : Mouse.MouseUp