WPF MouseLeftButtonDown 被执行多次,防止MouseLeftButtonUp 冒泡

本文详细解析了WPF中鼠标事件的执行流程,包括预览事件和冒泡事件的区别,通过实例展示了不同类型的鼠标事件如何按顺序触发,并解释了这些事件在控件层级中的传递方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MouseLeftButtonDown 是冒泡事件,从下往根节点传递;PreviewMouseLeftButtonDown 是隧道事件,从根节点往下传递,所以换成PreviewMouseLeftButtonDown

1. 点击事件的执行顺序

  1. PreviewMouseLeftButtonDown
  2. PreviewMouseDown
  3. MouseLeftButtonDown
  4. MouseDown
  5. PreviewMouseLeftButtonUp
  6. PreviewMouseUp
  7. Click
  8. MouseLeftButtonUp
  9. 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值