gpt4 book ai didi

wpf - 如何在鼠标实际移动到元素上时获取 MouseMove 事件

转载 作者:行者123 更新时间:2023-12-03 21:57:13 29 4
gpt4 key购买 nike

基本上我想要做的是将自定义窗口的状态从最大化更改为正常状态并调整窗口的位置,当用户单击并将鼠标移到 TitleBar 上时,在我的例子中这是一个简单的边框。

显而易见的事情是将事件处理程序附加到 MouseMove 并检查是否按下了鼠标左键:

    private void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Console.WriteLine("Mouse moved" + Mouse.Captured);
}
}

问题是 MouseMove 在鼠标捕获更改时发生。所以在我的应用程序中,在您打开弹出窗口并单击边框后,窗口将捕捉到 Normal 状态,捕捉应该在您开始拖动后发生。

下面是上述代码的XAML来证明问题:

 <Grid MouseMove="OnMouseMove" Background="AliceBlue">
<ComboBox Height="23">
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
</ComboBox>
</Grid>

问题步骤,调试运行上面的代码:

  1. 单击 ComboBox 打开其弹出窗口。
  2. 单击蓝色网格(这将关闭弹出窗口)。

注意:输出窗口显示消息“鼠标移动”

预期行为:因为只进行了一次点击(没有鼠标移动),所以我不需要 MouseMove 事件。

我知道当 Mouse.Captured 元素改变时 MouseMove 被触发,这是正常的,但我需要一种方法来区分正常的 MouseMove 和由鼠标捕获引起的 MouseMove

编辑:

这个问题的一个更复杂的例子可以在 MahApps.Metro 演示中找到。步骤与上述相同——当窗口处于最大化状态时,打开一个弹出窗口并单击标题栏。您会注意到窗口从最大化状态快速切换到正常状态。这不应该发生,因为您没有双击或拖动标题栏。

我目前的解决方案:

因为我知道这是由鼠标捕获的元素变化引起的,所以我处理了 LostMouseCapture 事件并保存了鼠标位置:

    private Point mousePositionAfterCapture;

private void OnLostMouseCapture(object sender, MouseEventArgs e)
{
mousePositionAfterCapture = e.GetPosition(this);
}

MouseMove 处理程序中,我检查在上次丢失鼠标捕获后位置是否发生了变化:

private void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point currentPossition = e.GetPosition(this);

if (currentPossition == mousePositionAfterCapture)
//means that the MouseMove event occurred as a result of
//Mouse Captured element change, we wait until an actual
//mouse move will occure
return;

Console.WriteLine("Mouse moved" + Mouse.Captured);
}
}

最佳答案

随着我对拖动的了解越来越多,我会自己回答这个问题。拖动是一个应该在鼠标移动和鼠标左键按下时开始的操作,但它不应该立即开始,以防止意外开始拖动 SystemParameters.MinimumHorizo​​ntalDragDistanceSystemParameters .MinimumVerticalDragDistance 应使用静态成员。

private Point startPoint;

private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(null);
}

private void OnPreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point position = e.GetPosition(this);

if (Math.Abs(position.X - startPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(position.Y - startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
{
StartDrag(e);
}
}
}

这解决了这个问题中提出的问题,因为如果鼠标没有改变其位置,拖动将永远不会开始。

关于wpf - 如何在鼠标实际移动到元素上时获取 MouseMove 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21550982/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com