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?

Foi útil?

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;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top