5

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

简单原理(示意图):

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

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

我沿着水平轴移动标签。MouseDown(设置 LastX)然后继续。没有人知道什么时候停止,只有鼠标移动的感觉。当然,我可以MouseUp用来知道移动何时结束,但是如果用户按住按钮并停止移动,我想反映最新的标签位置。

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

试过了

label.Visible = false
label.Location.X += deltaX
label.Visible = true

没有帮助。

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

4

1 回答 1

2

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

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

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

这个 SO 问题

[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
}
于 2010-03-22T21:38:51.133 回答