Переместите PictureBox с помощью мыши - PullRequest
2 голосов
/ 20 февраля 2009

Я занимаюсь разработкой приложения для Windows Mobile (Compact Framework 2.0). У него есть WinForms с PictureBox.

Я хочу переместить изображение PictureBox, но я не знаю, как это сделать, поэтому я решил переместить отверстие PictureBox.

Для этого я использую это событие:

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

Но когда я перемещаю PictureBox, он мигает и перемещается везде.

Что я делаю не так?

Ответы [ 6 ]

6 голосов
/ 20 февраля 2009

e.X и e.Y относятся к графическому блоку (например, если мышь находится в верхнем левом углу графического блока, это 0,0).

Значения imagenMapa.Left и imagenMapa.Top относятся к форме (или любому другому элементу управления imagenMapa)

Если вы попытаетесь смешать значения из этих двух систем без преобразования, вы получите скачки (как вы видите).

Возможно, вам лучше преобразовать положение мыши в ту же систему координат, которая используется для объекта, содержащего графическое поле.

Вы можете использовать imagenMapa.PointToScreen, чтобы получить координаты мыши в экранных координатах (или Cursor.Position, чтобы получить позицию непосредственно), и yourForm.PointToClient вернуть их обратно в форму координат.

Обратите внимание, что в зависимости от ваших потребностей, вы можете выполнить "перемещение изображения внутри элемента управления", переопределив / обработав событие Paint элемента управления и нарисовав изображение самостоятельно. Если бы вы сделали это, вы могли бы сохранить все в координатах Picturebox, так как они, вероятно, будут использоваться при вызове graphicsObject.DrawImage.

5 голосов
/ 01 февраля 2013

Фактический код (требуется .NET Framework 3.5 и выше, не уверен, что это доступно в 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;
};
1 голос
/ 19 мая 2012

Объять математику!

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

Быстрое объяснение: Вы получаете разницу от положений мыши и применяете ее к объекту, который хотите переместить.

Пример: Если старая X-позиция мыши равна 382, ​​а новая - 385, то разница равна -3. Если текущая позиция X управления равна 10, то 10 - (-3) = 13

Почему: Он работает для чего угодно и намного дешевле, чем постоянное преобразование координат назад и вперед.

1 голос
/ 20 февраля 2009

Также не забудьте установить для вашей формы двойную буферизацию, что может помочь с мерцанием, но для ее фактического позиционирования мне нравится предложение Дэниела Л.

1 голос
/ 20 февраля 2009

e.X & e.Y находится в координатном пространстве pictureBox, imagenMapa.Left & imagenMapa.Top находится в координатном пространстве формы. : -)

0 голосов
/ 08 февраля 2017

На самом деле то, что вы сделали, правильно. Но вы предоставили свойство MouseMove для графического окна. Вы должны передать это свойство в форму (фон).

например:

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