我使用 MouseMove 事件来移动对象(比如标签)。
简单原理(示意图):
OnMouseMove(e MouseEventArgs)
if e.Button == Left
deltaX = e.X - lastX
foreach label in labels
label.Location.X += deltaX
lastX = e.X
一旦标签数量增加,我开始看到沿着移动轨迹的标签痕迹。
我有 I I I II III II I I III II 之类的东西,但想拥有 I I I I 之类的东西作为痕迹。我想知道鼠标什么时候“开始”和“停止移动”这样的事情。
我沿水平轴移动标签。
MouseDown
(设置 LastX)然后继续。没有人知道什么时候停止,只有鼠标移动的感觉。我当然可以使用 MouseUp
知道移动何时结束,但是如果用户保持按钮按下并停止移动,我想反射(reflect)最新的标签位置。有没有办法防止这种痕迹?
试过了
label.Visible = false
label.Location.X += deltaX
label.Visible = true
没有帮助。
parent.SuspendLayout 和 ResumeLayout 没有多大帮助,因为我需要在每次鼠标移动时都这样做,所以任何效果。
最佳答案
编辑:我刚刚注意到您关于鼠标何时停止的编辑。您可以使用计时器来帮助您。将一个设置为您想要更新位置的时间间隔,并在时间结束时自动重置。在鼠标按下时启动它并在鼠标抬起时停止它。当计时器结束时,更新标签的位置。
--上下文的原始答案:--
是的,您可以在父控件上暂停绘制,移动标签,然后恢复绘制和刷新。
来自 this SO question :
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
private const int WM_SETREDRAW = 11;
public static void SuspendDrawing(Control parent)
{
SendMessage(parent.Handle, WM_SETREDRAW, false, 0);
}
public static void ResumeDrawing(Control parent)
{
SendMessage(parent.Handle, WM_SETREDRAW, true, 0);
parent.Refresh();
}
示例用法:
private void OnMouseMove(MouseEventArgs e)
{
int deltaX = e.X - lastX;
// Suspend drawing here
foreach (Label label in labels)
{
label.Location.X += deltaX;
}
lastX = e.X;
// Resume drawing here
}
编辑:如果您只想在差值大于 n 个像素时显示位置的变化,那么您应该使用勾股定理来计算旧位置和新位置之间的距离,并且只有在差值大于 n 时才移动它。当鼠标按钮出现时,将标签移动到它们应该根据鼠标所在的位置。
伪代码:
difference = Math.Sqrt(x * x, y * y);
if (difference > n) // n is whatever number you want
{
// move the labels
// set the old position to the new position
}
关于.net - 鼠标移动灵敏度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2495870/