Mover um PictureBox com o mouse
-
05-09-2019 - |
Pergunta
Estou desenvolvendo um aplicativo para Windows Mobile (Compact Framework 2.0). Tem um WinForms com um PictureBox.
Eu quero passar a imagem da PictureBox mas eu não sei como fazê-lo assim que eu escolher para mover o buraco PictureBox.
Para fazer isso eu uso este evento:
private void imagenMapa_MouseMove(object sender, MouseEventArgs e)
{
imagenMapa.Left = e.X;
imagenMapa.Top = e.Y;
this.Refresh();
}
Mas quando eu mover o PictureBox pisca e se move em todos os lugares.
O que eu estou fazendo errado?
Solução
O e.X
e e.Y
são em relação ao caixa de imagem (por exemplo, se o mouse está no canto superior esquerdo da caixa de imagem, que é 0,0).
Os valores para imagenMapa.Left
e imagenMapa.Top
são em relação à forma (ou seja o controlo contém imagenMapa
)
Se você tentar misturar os valores desses dois sistemas sem conversão, você está indo para obter saltos (como você está vendo).
Você é provavelmente melhor converter a posição do mouse com o mesmo sistema de coordenadas utilizado pela coisa que contém a caixa de imagem.
Você pode usar imagenMapa.PointToScreen
para obter as coordenadas do mouse em coordenadas de tela (ou Cursor.Position
para obter a posição diretamente), e yourForm.PointToClient
para recuperá-los nas coordenadas do formulário.
Note que, dependendo de suas necessidades, você poderia realizar "mover uma imagem dentro de um controle", substituindo / manusear o Paint
evento de um controle e desenhar a imagem si mesmo. Se você fez isso, você pode manter tudo nas coordenadas PictureBox, já que esses são provavelmente o que você usaria quando você chamada graphicsObject.DrawImage
.
Outras dicas
código real (Requer .NET Framework 3.5 e além, não sei se isso está disponível no 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 & e.Y está no espaço de coordenadas do pictureBox, imagenMapa.Left & imagenMapa.Top é no espaço de coordenadas do formulário. : -)
Também não se esqueça de definir o formulário para dobro tamponada, que ajuda força com a cintilação, mas para o posicionamento real dele, eu como sugestão de Daniel L's
matemática abraço!
control.Left = control.Left - (_lastMousePos.X - currentMousePos.X);
control.Top = control.Top - (_lastMousePos.Y - currentMousePos.Y);
explicação rápida: Você começa a diferença entre as posições de mouse e aplicá-lo para o objeto que você deseja mover.
Exemplo: Se a antiga posição do rato X é 382, ??e o novo é 385, em seguida, a diferença é -3. Se o controlo actual posição X é 10, em seguida, 10 - (-3) = 13
Por: Ele funciona para qualquer coisa, e é muito mais barato do que constantemente converter coordenadas e para trás.
Na verdade o que você tem feito é correto. Mas você deu a propriedade MouseMove para o picturebox. Você deve dar essa propriedade para o formulário (background).
ex:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
imagenMapa.Left = e.X;
imagenMapa.Top = e.Y;
}