Вопрос

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

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

Чтобы сделать это, я использую это событие:

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

Другие советы

Фактический код (требуется .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;
};

e.X и e.Y находятся в координатном пространстве PictureBox, imagenMapa.Слева и imagenMapa.Вверху находятся в координатном пространстве формы.:-)

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

Примите математику!

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

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

На самом деле то, что вы сделали, правильно.Но вы присвоили свойство MouseMove picturebox.Вы должны присвоить это свойство Форме (background).

бывший:

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
  imagenMapa.Left = e.X;
  imagenMapa.Top = e.Y;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top