5

オブジェクト (ラベルなど) を移動するには、MouseMove イベントを使用します。

単純な原理 (回路図):

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

ラベルの数が増えると、移動軌跡に沿ってラベルのトレースが見え始めます。Ⅲ Ⅱ Ⅲ Ⅱ Ⅲ Ⅱ みたいなのがあるんですけど、痕跡として Ⅲ みたいなのが欲しいです。マウスがいつ「動き始め」、「動きが止まる」かを知りたいです。

水平軸に沿ってラベルを移動します。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 に答える