c# - sizemode - picturebox visual studio 2017
Mueva un PictureBox con el mouse (6)
Estoy desarrollando una aplicación para Windows Mobile (Compact Framework 2.0). Tiene un wimforms con un cuadro de imagen.
Quiero mover la imagen de pictureBox pero no sé cómo hacerlo, así que elijo mover el cuadro de imagen del agujero. 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 la PictureBox, parpadea y se mueve hacia todos lados.
¿Qué estoy haciendo mal?
¡Gracias!
El eX
y eY
son relativos al cuadro de la imagen (por ejemplo, si el mouse está en la eY
superior izquierda del cuadro de la imagen, eso es 0,0).
Los valores para imagenMapa.Left
y imagenMapa.Top
son relativos a la forma (o cualquier control que contenga imagenMapa
)
Si intenta mezclar valores de estos dos sistemas sin conversión, obtendrá saltos (como los que está viendo).
Probablemente sea mejor que convierta la posición del mouse al mismo sistema de coordenadas utilizado por la cosa que contiene el cuadro de imagen.
Puede usar imagenMapa.PointToScreen
para obtener las coordenadas del mouse en coordenadas de pantalla (o Cursor.Position
para obtener la posición directamente) y yourForm.PointToClient
para recuperarlas en las coordenadas del formulario.
Tenga en cuenta que, según sus necesidades, podría lograr "mover una imagen dentro de un control" anulando / manipulando el evento Paint
de un control y dibujando la imagen usted mismo. Si hiciera esto, podría mantener todo en las coordenadas de la imagen, ya que es probable que sea lo que utilizaría cuando llame a graphicsObject.DrawImage
.
Tampoco olvides configurar tu formulario en doble búfer, que podría ayudar con el parpadeo, pero para el posicionamiento real de la misma, me gusta la sugerencia de Daniel L.
eX y eY se encuentran en el espacio de coordenadas de pictureBox, imagenMapa.Left & imagenMapa.Top está en el espacio de coordenadas del formulario. :-)
¡Adopta las matemáticas!
control.Left = control.Left - (_lastMousePos.X - currentMousePos.X);
control.Top = control.Top - (_lastMousePos.Y - currentMousePos.Y);
Explicación rápida: obtiene la diferencia de las posiciones del mouse y la aplica al objeto que desea mover.
Ejemplo: Si la antigua posición X del ratón es 382, y la nueva es 385, entonces la diferencia es -3. Si la posición actual de los controles X es 10, entonces 10 - (-3) = 13
Por qué: Funciona para cualquier cosa, y es mucho más económico que la conversión constante de coordenadas hacia adelante y hacia atrás.
Código actual (Requiere .NET Framework 3.5 y más allá, no estoy seguro si esto está disponible en el Marco Compacto) ...
// 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;
};
En realidad, lo que has hecho es correcto. Pero le diste la propiedad MouseMove al cuadro de imagen. Debes darle esa propiedad al Formulario (fondo).
ex:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
imagenMapa.Left = e.X;
imagenMapa.Top = e.Y;
}