MouseMove敏感

ser*_*hio 5 .net controls mousemove winforms

我使用MouseMove事件来移动对象(比如标签).

简单原理(原理图):

OnMouseMove(e MouseEventArgs)
    if e.Button == Left
        deltaX = e.X - lastX
        foreach label in labels
            label.Location.X += deltaX
        lastX = e.X
Run Code Online (Sandbox Code Playgroud)

一旦标签数量增加,我就会开始看到沿着移动轨迹的标签痕迹.我有类似III II III II II III的东西,但想要像IIII这样的痕迹.我想知道什么时候鼠标"开始"和"停止移动"这样的东西.

我沿着水平轴移动标签.MouseDown(设置LastX)继续.没有人知道何时停止,只有鼠标移动敏感性.当然我可以MouseUp用来知道运动何时结束,但是如果用户保持按钮向下并停止移动,我想反映最新的标签位置.

有没有办法防止这种痕迹?

试着

label.Visible = false
label.Location.X += deltaX
label.Visible = true
Run Code Online (Sandbox Code Playgroud)

没有帮助.

parent.SuspendLayout和ResumeLayout没有多大帮助,因为我需要在每次鼠标移动时都这样做,所以任何效果.

Zac*_*son 2

编辑:我刚刚注意到您对鼠标何时停止的编辑。您可以使用计时器来帮助您。将其设置为您想要更新位置的时间间隔,并在时间过去后自动重置。鼠标按下时启动,鼠标松开时停止。当计时器到期时,更新标签的位置。

--上下文的原始答案: --

是的,您可以暂停父控件上的绘制,移动标签,然后恢复绘制并刷新。

这个问题来看:

[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();
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

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
}
Run Code Online (Sandbox Code Playgroud)

编辑:如果您只想在差异大于 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
}
Run Code Online (Sandbox Code Playgroud)