【问题标题】:WPF Mousedown => No MouseLeave EventWPF Mousedown => 没有 MouseLeave 事件
【发布时间】:2010-09-26 12:50:52
【问题描述】:

我正在使用 Microsoft Blend 构建 Windows Presentation Foundation 控件。

当我通过按下鼠标左键离开我的控制时,不会引发 MouseLeave-Event。为什么不呢?

【问题讨论】:

  • 您可以控制什么?我认为这是因为控件中接收到 MouseDown 事件的对象(例如按钮)已将“Mouse.IsCaptured”设置为 true,因此它专门处理 MouseEvents。
  • 这只是一个边框、网格、图像和 2 个标签。这可能吗?
  • 我们遇到了同样的问题(见问题:stackoverflow.com/questions/15970248/…)。所以我在这里开始赏金以引起人们的注意。

标签: wpf events mouse


【解决方案1】:

这是预期的行为:当您在控件上执行mousedown 并离开控件时,控件仍将其“捕获”保留在鼠标上,这意味着控件不会触发MouseLeave-Event。一旦鼠标按钮在控件之外释放,就会触发 Mouse-Leave 事件。

为避免这种情况,您可以简单地告诉您的控件根本不要捕获鼠标:

private void ControlMouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
    Control control = (Control) sender;
    control.Capture = false; //release capture.
}

现在即使在按下按钮时移出,也会触发 MouseLeave 事件。

如果您需要在控件内进行捕获,则需要付出更多的努力:

  • 在按下鼠标键时手动开始跟踪鼠标位置

  • 将位置与相关控件的TopLeftSize 属性进行比较。

  • 决定是否需要停止捕获鼠标的控件。

    public partial class Form1 : Form
    {
    private Point point;
    private Boolean myCapture = false;
    
    public Form1()
    {
        InitializeComponent();
    }
    
    private void button1_MouseDown(object sender, MouseEventArgs e)
    {
        myCapture = true;
    }
    
    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if (myCapture)
        {
            point = Cursor.Position;
    
            if (!(point.X > button1.Left && point.X < button1.Left + button1.Size.Width && point.Y > button1.Top && point.Y < button1.Top + button1.Size.Height))
            {
                button1.Capture = false; //this will release the capture and trigger the MouseLeave event immediately.
                myCapture = false;
            }
        }
    }
    
    private void button1_MouseLeave(object sender, EventArgs e)
    {
        MessageBox.Show("Mouse leaving");
    }
    

    }

当然,您需要在 MouseUp 上停止自己的跟踪 (myCapture=false;)。忘了那个:)

【讨论】:

  • 但是如果我需要在鼠标离开整个窗口时提升 MouseLeave 怎么办?我想当鼠标不在窗口时我不会收到 MouveMouve 事件,因此基于 MouseMove 的解决方案将无法工作。还是我错了?
  • @Idsa 它也适用于表单。
  • 但是我们在这里谈论的是WPF。我怀疑它是否适用于 WPF 窗口
  • @Idsa Fogot 更新我的答案。我测试它,它不适用于 Windows,你是对的。原因是当鼠标离开表单时 mouseMove 事件不会更新。不确定,如果这与问题有关,因为 TC 声明存在“控件”问题。
  • 控件没有 Capture 属性!
【解决方案2】:

当我没有收到鼠标事件时,我通常会使用 Snoop 来帮助我了解正在发生的事情。

这里有几个链接:

1-Snoop (a WPF utility)
2-CodePlex project for Snoop

【讨论】:

  • 这并不能真正回答问题。
【解决方案3】:

并且出于完整性和历史原因(不是赏金 - 有两个重复的问题是没有意义的 - 如果为时不晚,您可能应该将其移入一个)...

我在这里使用global mouse hook 做了一个彻底的解决方案(方法2)
WPF: mouse leave event doesn't trigger with mouse down

并简化了它的使用 - 您可以通过绑定到视图模型中的命令来使用它 - 例如

my:Hooks.EnterCommand="{Binding EnterCommand}"
my:Hooks.LeaveCommand="{Binding LeaveCommand}"
my:Hooks.MouseMoveCommand="{Binding MoveCommand}"

...那里有更多详细信息

【讨论】:

    【解决方案4】:

    老问题,但我遇到了与按钮相同的问题(MouseLeave 在 MouseDown 时不会触发,因为 MouseDown 捕获鼠标...)

    反正我就是这样解决的:

    element.GotMouseCapture += element_MouseCaptured;
    
    static void element_MouseCaptured(object sender, MouseEventArgs e)
    {
        FrameworkElement element = (FrameworkElement)sender;
        element.ReleaseMouseCapture();
    }
    

    希望对寻求快速修复的人有所帮助:P

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-15
      相关资源
      最近更新 更多