按下鼠标并单击冲突
本文关键字:单击 冲突 鼠标 | 更新日期: 2023-09-27 18:03:07
我在form_MouseDown事件上有一个Drag()方法。我在表单上也有一个点击事件。问题是,如果我点击表单,MouseDown事件被触发,它从来没有机会触发点击事件。
解决这个问题的最好方法是什么?我在想计数像素,如果形式是实际拖动,但必须有一个更好的方法。有什么建议吗?
我想计数像素,如果表单实际上是拖动的,但必须有一个更好的方法。
不,这正是你必须做的。
这不仅仅是软件限制;这也是一个非常实用的方法。如果您从用户的角度考虑问题,您将立即看到问题和解决方案。问问你自己,点击和拖动的区别是什么?
它们都以鼠标按钮向下移动到对象上开始,但其中一个以鼠标按钮向上移动到对象上的相同位置结束,而另一个以鼠标按钮向上移动到完全不同的位置结束。
由于时间机器尚未完善,你无法提前知道这一点。
所以,是的,你需要保持某种距离阈值,如果指针移动到距离阈值之外,而它是向下的对象,那么你认为它是一个拖动。否则,你认为它是一个点击。
距离阈值不应该为0。不应该要求用户保持鼠标完全不动,以启动单击。许多用户都是不合格的鼠标点击者。他们很可能在尝试点击时轻微抽搐。如果阈值为0,当他们尝试点击时,他们将会做很多无意的拖动。
当然,您实际上不必担心这些,也不必自己计算拖动阈值。相反,使用Windows的默认值,可以通过调用GetSystemMetrics
函数并指定SM_CXDRAG
或SM_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"answers"button up"。
对于拖动,决定因素是"移动"answers"按钮向上"。
因此,为了消除这些交互作用的歧义,您不仅要跟踪按钮,还要跟踪运动。你不需要跟踪整个运动,只有在按下和按上之间的运动是有趣的。
因此,这些事件是启动/停止鼠标的好地方。捕获机制(动态呈现拖动装饰符和放置位置提示),或者,以更简单的形式—存储移动矢量的原点和目标并检查距离是否> D(即使发生了移动,也应该有一些安全的最小距离,在该距离内取消拖动。鼠标有时"参差不齐",人们真的不希望你的应用程序开始拖拽,当他们双击鼠标指针快速移动结束:))