Pregunta

Estoy desarrollando una aplicación para Windows Mobile (Compact Framework 2.0).Tiene WinForms con PictureBox.

Quiero mover la imagen del PictureBox pero no sé cómo hacerlo, así que elijo mover el PictureBox hueco.

Para hacerlo utilizo este evento:

private void imagenMapa_MouseMove(object sender, MouseEventArgs e)
{
      imagenMapa.Left = e.X;
      imagenMapa.Top = e.Y;
      this.Refresh();
}

Pero cuando muevo el PictureBox, parpadea y se mueve por todas partes.

¿Qué estoy haciendo mal?

¿Fue útil?

Solución

El e.X y e.Y son en relación con el cuadro de imagen (por ejemplo, si el ratón está en la parte superior izquierda de la caja de imagen, que es 0,0).

Los valores para imagenMapa.Left y imagenMapa.Top son en relación con la forma (o lo que sea de control contiene imagenMapa)

Si intenta mezclar los valores de estos dos sistemas sin conversión, que van a obtener saltos (como se está viendo).

es probablemente mejor de la conversión de la posición del ratón en el mismo sistema de coordenadas utilizado por lo que contiene el cuadro de imagen.

Se puede usar imagenMapa.PointToScreen para obtener las coordenadas del ratón en coordenadas de pantalla (o Cursor.Position para obtener la posición directamente), y yourForm.PointToClient para recuperarlos en las coordenadas de formulario.

Tenga en cuenta que dependiendo de sus necesidades, que podría lograr "movimiento de una imagen dentro de un control" anulando / manejo de la Paint caso de un control y dibujar la imagen de sí mismo. Si usted hizo esto, se podía mantener todo en las coordenadas PictureBox, ya que esos son probablemente la que se uso cuando llamó graphicsObject.DrawImage .

Otros consejos

código real (Requiere .NET Framework 3.5 y más allá, no estoy seguro si esto está disponible en el Compact Framework) ...

// Global Variables
private int _xPos;
private int _yPos;
private bool _dragging;

// Register mouse events
pictureBox.MouseUp += (sender, args) =>
{
    var c = sender as PictureBox;
    if (null == c) return;
    _dragging = false;
};

pictureBox.MouseDown += (sender, args) =>
{
    if (args.Button != MouseButtons.Left) return;
    _dragging = true;
    _xPos = args.X;
    _yPos = args.Y;
};

pictureBox.MouseMove += (sender, args) =>
{
    var c = sender as PictureBox;
    if (!_dragging || null == c) return;
    c.Top = args.Y + c.Top - _yPos;
    c.Left = args.X + c.Left - _xPos;
};

e.X y e.Y está en el espacio de coordenadas del cuadro de imagen, imagenMapa.Left y imagenMapa.Top está en el espacio de coordenadas del formulario. : -)

También no se olvide de ajustar su forma de doble buffer, que podrían ayudar con el parpadeo, pero para el posicionamiento real de la misma, me gusta Daniel L's sugerencia

¡Abraza las matemáticas!

control.Left = control.Left - (_lastMousePos.X - currentMousePos.X);
control.Top = control.Top - (_lastMousePos.Y - currentMousePos.Y);

Explicación rápida:Obtienes la diferencia de las posiciones del mouse y la aplicas al objeto que deseas mover.

Ejemplo:Si la antigua posición X del mouse es 382 y la nueva es 385, entonces la diferencia es -3.Si la posición X actual del control es 10, entonces 10 - (-3) = 13

Por qué:Funciona para cualquier cosa y es mucho más económico que convertir constantemente coordenadas de un lado a otro.

En realidad lo que ha hecho es correcto. Pero le dio la propiedad MouseMove al cuadro de imagen. Usted debe dar a esa propiedad a la forma (de fondo).

por ejemplo:

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
  imagenMapa.Left = e.X;
  imagenMapa.Top = e.Y;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top