2010-03-22 20 views
5

Uso el evento MouseMove para mover objetos (por ejemplo, etiquetas).MouseMove sensibilidad

principio simple (esquema):

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

Una vez que el aumento de número de etiquetas, comienzo a ver las etiquetas traza a lo largo de la trayectoria de movimiento. Tengo algo así como I I II III II I I III II, pero quiero tener algo como I I I I como rastros. Me gustaría saber cuándo el mouse "comienza" y "se detiene para moverse" algo así.

Muevo las etiquetas a lo largo de un eje horizontal. MouseDown (establecer LastX) y continuar. Nadie sabe cuándo se detiene, solo la sensibilidad del movimiento del mouse. Sin duda, puedo usar MouseUp para saber cuándo termina el movimiento, pero si el usuario mantiene el botón presionado y deja de moverse, quiero reflejar la última posición de la etiqueta.

¿Hay alguna manera de evitar este tipo de rastros?

trataron

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

no ayuda.

parent.SuspendLayout y ResumeLayout no ayuda mucho, porque necesito hacer esto en cada movimiento del mouse, por lo que cualquier efecto.

Respuesta

2

Editar: he acabo de dar cuenta de su edición de cuando las paradas del ratón. Podría usar un cronómetro para ayudarlo. Haga que uno se ajuste al intervalo en el que desea actualizar las posiciones y que se restablezca automáticamente cuando haya transcurrido. Comience con el mouse hacia abajo y deténgalo con el mouse hacia arriba. Cuando el temporizador haya transcurrido, actualice las ubicaciones de las etiquetas.

- Respuesta original de contexto: -

Sí, puede suspender dibujo en el control de los padres, mover las etiquetas, y luego retomar el dibujo y refrescar.

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

Ejemplo de Uso:

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 
} 

Editar: Si sólo desea mostrar el cambio de posición si la diferencia es mayor que n píxeles, entonces debería use el Teorema de Pitágoras para calcular la distancia entre la posición anterior y la nueva posición y solo muévala si la diferencia es mayor que n. Cuando aparezca el botón del mouse, mueve las etiquetas a la ubicación que se supone que deben estar de acuerdo con el mouse.

Pseudo-código:

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. El problema es que muevo las etiquetas con mucha frecuencia. Tengo algo así como I I II II III II I I III II, pero quiero tener algo como I I I I I I I como rastros. Me gustaría saber cuándo el mouse "comienza" y "se detiene para moverse" algo así. Puedo hacer también el parent.Suspend/ResumeLayout() pero ... ¿cuándo? – serhio

+0

@serhio: He editado para incluir un ejemplo de cómo puede utilizar SuspendDrawing/ResumeDrawing. Si te entiendo correctamente, las etiquetas no se mueven "juntas" (las ves moverse por separado). Esta solución se encargará de eso. –

+0

@Zach. Sí. pero...el problema es que quiero hacer en lugar de hacer 10 movimientos (digamos del 1 al 20) solo 5. En gros, cuando muevo el "contenedor de etiquetas" no necesito ver las etiquetas en movimiento, solo comienzo la final, y quizás una punto intermedio es suficiente. – serhio

Cuestiones relacionadas