質問

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 II II IIのようなものを持っていますが、痕跡としてIIIIのようなものが欲しいです。マウスがいつ「開始」され、「停止して移動する」ことを知りたいです。

水平軸に沿ってラベルを移動します。 MouseDown(lastxを設定)して続けます。停止する時期は誰も知りません。マウスだけが感性を移動します。確かに私は使用できます MouseUp 動きがいつ終了するかを知るために、ただし、ユーザーがボタンを維持して移動を停止した場合、最新のラベルの位置を反映したいと思います。

この種の痕跡を防ぐ方法はありますか?

試してみました

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

助けにならない。

parent.suspendlayoutとresumelayoutは、あまり役に立ちません。すべてのマウスの動きでこれを行う必要があるため、効果はありません。

役に立ちましたか?

解決

編集: マウスがいつ停止するかについて編集したことに気付きました。タイマーを使用して役立ちます。ポジションを更新する間隔に1つのセットを用意し、経過時に自動リセットします。マウスで起動して、マウスで停止します。タイマーが経過したら、ラベルの場所を更新します。

--コンテキストのための元の答え:--

はい、親のコントロールの描画を一時停止し、ラベルを移動してから、描画と更新を再開できます。

から これはとても質問です:

[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
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top