MouseMove敏感

时间:2010-03-22 21:25:32

标签: .net winforms controls mousemove

我使用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 III III II I III III II的东西,但我希望拥有像我这样的东西作为痕迹。我想知道什么时候鼠标“开始”和“停止移动”这样的东西。

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

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

尝试

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

无济于事。

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

1 个答案:

答案 0 :(得分:2)

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

- 上下文的原始答案: -

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

来自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
}