我正在开发一个适用于 Windows Mobile(Compact Framework 2.0)的应用程序。它有一个带有 PictureBox 的 WinForms。

我想移动PictureBox的图像,但我不知道该怎么做,所以我选择移动PictureBox的洞。

为此,我使用此事件:

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

但是当我移动 PictureBox 时,它会闪烁并移动到各处。

我做错了什么?

有帮助吗?

解决方案

e.Xe.Y 是相对于图片框的(例如如果鼠标位于图片框的左上角,则为 0,0) 。

的值 imagenMapa.LeftimagenMapa.Top 与表单相关(或任何控件包含 imagenMapa)

如果您尝试混合来自这两个系统的值而不进行转换,您将会得到跳跃(就像您所看到的)。

您最好将鼠标位置转换为包含图片框的物体所使用的相同坐标系。

你可以使用 imagenMapa.PointToScreen 获取屏幕坐标中的鼠标坐标(或 Cursor.Position 直接获取位置),以及 yourForm.PointToClient 让它们回到表单坐标中。

请注意,根据您的需要,您可以通过覆盖/处理来完成“在控件内移动图像” Paint 事件 控件并自己绘制图像。如果您这样做,您可以将所有内容保留在图片框坐标中,因为这些可能是您调用时会使用的内容 graphicsObject.DrawImage.

其他提示

实际代码(需要.NET Framework 3.5的超越,不知道这是可以在契约框架)...

// 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是在图片框,imagenMapa.Left&imagenMapa.Top的坐标空间是在窗体的坐标空间。 : - )

另外,不要忘记设置你的模板在双缓冲,可能与闪烁的帮助,但它的实际的定位,我很喜欢丹尼尔·L的建议

拥抱数学!

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

为什么: 它适用于任何东西,比便宜得多不断转换坐标来回。

其实你做了什么是正确的。但是,你给鼠标移动属性PictureBox的。你应该给这个属性的表格(背景)。

例如:

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
  imagenMapa.Left = e.X;
  imagenMapa.Top = e.Y;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top