按下鼠标并单击冲突



我在form_MouseDown事件上有一个Drag()方法。我在表单上也有一个点击事件。问题是,如果我点击表单,MouseDown事件被触发,它从来没有机会触发点击事件。

解决这个问题的最好方法是什么?我在想计数像素,如果形式是实际拖动,但必须有一个更好的方法。有什么建议吗?

我想计数像素,如果表单实际上是拖动的,但必须有一个更好的方法。

不,这正是你必须做的。

这不仅仅是软件限制;这也是一个非常实用的方法。如果您从用户的角度考虑问题,您将立即看到问题和解决方案。问问你自己,点击和拖动的区别是什么?

它们都以鼠标按钮向下移动到对象上开始,但其中一个以鼠标按钮向上移动到对象上的相同位置结束,而另一个以鼠标按钮向上移动到完全不同的位置结束。

由于时间机器尚未完善,你无法提前知道这一点。

所以,是的,你需要保持某种距离阈值,如果指针移动到距离阈值之外,而它是向下的对象,那么你认为它是一个拖动。否则,你认为它是一个点击。

距离阈值不应该为0。不应该要求用户保持鼠标完全不动,以启动单击。许多用户都是不合格的鼠标点击者。他们很可能在尝试点击时轻微抽搐。如果阈值为0,当他们尝试点击时,他们将会做很多无意的拖动。

当然,您实际上不必担心这些,也不必自己计算拖动阈值。相反,使用Windows的默认值,可以通过调用GetSystemMetrics函数并指定SM_CXDRAGSM_CYDRAG来获得。(这些可能会暴露在WinForms框架的某个地方,但我不这么认为。你也可以自己P/调用它们)

const int SM_CXDRAG = 68;
const int SM_CYDRAG = 69;
[DllImport("user32.dll")]
static extern int GetSystemMetrics(int index);
Point GetDragThreshold()
{
    return new Point(GetSystemMetrics(SM_CXDRAG), GetSystemMetrics(SM_CYDRAG));
}

在UX/UI领域,这类东西被称为迟滞脱噪,类似于这些术语在物理学和电子学中的使用。

我找到了这个解决方案,尽管它适用于双击和鼠标按下事件:

void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && e.Clicks ==1)
{
PictureBox pb = (PictureBox)sender;
DoDragDrop((ImageData)pb.Tag, DragDropEffects.Copy);
}
}

来源:http://code.rawlinson.us/2007/04/c-dragdrop-and-doubleclick.html

不幸的是,当"button-is-pressed"时,您还不知道想要的操作是单击还是拖放。

对于点击,行列式为"no movement"one_answers"button up"。

对于拖动,决定因素是"移动"one_answers"按钮向上"。

因此,为了消除这些交互作用的歧义,您不仅要跟踪按钮,还要跟踪运动。你不需要跟踪整个运动,只有在按下和按上之间的运动是有趣的。

因此,这些事件是启动/停止鼠标的好地方。捕获机制(动态呈现拖动装饰符放置位置提示),或者,以更简单的形式—存储移动矢量的原点和目标并检查距离是否> D(即使发生了移动,也应该有一些安全的最小距离,在该距离内取消拖动。鼠标有时"参差不齐",人们真的不希望你的应用程序开始拖拽,当他们双击鼠标指针快速移动结束:))

最新更新