2010-03-22 8 views
5

Ich verwende MouseMove-Ereignis, um Objekte zu verschieben (sagen Etiketten).MouseMove sensibility

einfaches Prinzip (schematisch):

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

Sobald die Etiketten Zahl zu erhöhen, beginne ich die Etiketten zu sehen Spuren entlang der Bewegungsbahn. Ich habe so etwas wie ich I II III II I I III II, aber ich möchte etwas wie I I I I als Spuren haben. Ich würde gerne wissen, wann die Maus "startet" und "aufhört, sich zu bewegen".

Ich bewege Etiketten entlang einer horizontalen Axt. MouseDown (set LastX) und weitermachen. Niemand weiß wann Stopps, nur die Maus bewegt die Sensibilität. Sicher kann ich MouseUp verwenden, um zu wissen, wann die Bewegung endet, aber jedoch, wenn Benutzer die Taste unten hält und aufhört, sich zu bewegen, möchte ich die späteste label Position reflektieren.

Gibt es eine Möglichkeit, diese Art von Spuren zu verhindern?

versucht

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

hilft nicht.

parent.SuspendLayout und ResumeLayout hilft nicht viel, weil ich dies bei jeder Mausbewegung tun muss, also jeden Effekt.

Antwort

2

Edit: Ich habe gerade bemerkt, bearbeiten Sie, wenn die Maus stoppt. Sie könnten einen Timer verwenden, um Ihnen zu helfen. Legen Sie fest, in welchem ​​Intervall die Positionen aktualisiert werden sollen, und setzen Sie sie automatisch zurück, wenn sie abgelaufen ist. Starte es mit der Maus nach unten und halte es mit der Maus an. Wenn der Timer abgelaufen ist, aktualisieren Sie die Positionen der Etiketten.

-Original-Antwort für Kontext: -

Ja, können Sie auf der übergeordneten Steuerung suspendieren zeichnen, um die Etiketten bewegen, und dann wieder ziehen und aufzufrischen.

Von 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(); 
} 

Verwendungsbeispiel:

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 
} 

Edit: Wenn Sie nur die Änderung der Position angezeigt werden soll, wenn die Differenz größer als n Pixel ist, dann sollten Sie Verwenden Sie den Satz des Pythagoras, um den Abstand zwischen der alten Position und der neuen Position zu berechnen und verschieben Sie ihn nur, wenn die Differenz größer als n ist. Wenn die Maustaste gedrückt wird, verschieben Sie die Beschriftungen an die Position, die sie gemäß der Maus sein sollen.

Pseudo-Code:

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 
} 
+0

hm. Das Problem ist, dass ich Etiketten sehr häufig verschiebe. Ich habe so etwas wie I I II III II I I III II, möchte aber etwas wie I I I I I I als Spuren haben. Ich würde gerne wissen, wann die Maus "startet" und "aufhört, sich zu bewegen". Ich kann auch die Eltern machen. Suspend/ResumeLayout() aber ... wann? – serhio

+0

@serhio: Ich habe ein Beispiel für die Verwendung von SuspendDrawing/ResumeDrawing hinzugefügt. Wenn ich Sie richtig verstehe, bewegen sich die Beschriftungen nicht "zusammen" (Sie sehen, dass sie sich getrennt bewegen). Diese Lösung wird dafür sorgen. –

+0

@ Zach. Ja. aber...das Problem ist, dass ich tun möchte, anstatt 10 Bewegungen (sagen wir von 1 bis 20) nur 5 zu machen. En gros, wenn ich den "Etikettencontainer" verschiebe, muss ich keine Etiketten bewegen sehen, sondern nur das Finale und vielleicht eins Zwischenpunkt ist genug. – serhio