C# 用鼠标移动图片框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/570582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:40:46  来源:igfitidea点击:

Move a PictureBox with mouse

c#winformspictureboxonmousemove

提问by VansFannel

I'm developing an app for windows mobile (Compact Framework 2.0). It has a WinForms with a PictureBox.

我正在为 windows mobile (Compact Framework 2.0) 开发一个应用程序。它有一个带有图片框的 WinForms。

I want to move the image of the PictureBox but I don't know how to do it so I choose to move the hole PictureBox.

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

To do it I use this event:

为此,我使用此事件:

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

But when I move the PictureBox it blinks and moves every where.

但是当我移动 PictureBox 时,它会闪烁并移动到任何地方。

What I'm doing wrong?

我做错了什么?

采纳答案by Daniel LeCheminant

The e.Xand e.Yare relative to the picture box (e.g. if the mouse is in the upper left of the picture box, that's 0,0) .

e.Xe.Y可相对于图像框(例如,如果鼠标在左上图片框,这就是0,0)。

The values for imagenMapa.Leftand imagenMapa.Topare relative to the form (or whatever control contains imagenMapa)

对值imagenMapa.LeftimagenMapa.Top相对于所述形式(或任何控件包含imagenMapa

If you try to mix values from these two systems without conversion, you're going to get jumps (like you're seeing).

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

You're probably better off converting the mouse position to the same coordinate system used by the thing that contains the picture box.

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

You could use imagenMapa.PointToScreento get the mouse coordinates in screen coordinates (or Cursor.Positionto get the position directly), and yourForm.PointToClientto get them back in the form coordinates.

您可以使用imagenMapa.PointToScreen在屏幕坐标中获取鼠标坐标(或Cursor.Position直接获取位置),并将yourForm.PointToClient它们返回到表单坐标中。

Note that depending on your needs, you could accomplish "moving an image within a control" by overriding/handling the Painteventof a control and drawing the image yourself. If you did this, you could keep everything in the picturebox coordinates, since those are likely what you would use when you called graphicsObject.DrawImage.

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

回答by Dan Bystr?m

e.X & e.Y is in the coordinate space of the pictureBox, imagenMapa.Left & imagenMapa.Top is in the coordinate space of the Form. :-)

eX & eY 在pictureBox 的坐标空间中,imagenMapa.Left & imagenMapa.Top 在Form 的坐标空间中。:-)

回答by Fry

Also don't forget to set your form to double buffered, that might help with the flickering, but for the actual positioning of it, I like Daniel L's suggestion

另外不要忘记将表单设置为双缓冲,这可能有助于解决闪烁问题,但对于它的实际定位,我喜欢 Daniel L 的建议

回答by insaina

Embrace math!

拥抱数学!

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

Quick explanation: You get the difference from the mouse positions and apply it to the object you want to move.

快速解释:您从鼠标位置获得差异并将其应用于要移动的对象。

Example: If the old mouse X position is 382, and the new one is 385, then the difference is -3. If the controls current X position is 10 then 10 - (-3) = 13

示例:如果旧鼠标X位置为382,新鼠标X位置为385,则差值为-3。如果控件当前的 X 位置为 10,则 10 - (-3) = 13

Why: It works for anything, and is much cheaper than constantly converting coordinates back and forth.

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

回答by theJerm

Actual Code (Requires .NET Framework 3.5 and beyond, not sure if this is available in the Compact Framework)...

实际代码(需要 .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;
};

回答by cdc

Actually what you have done is correct. But you gave the MouseMove property to the picturebox. You should give that property to the Form(background).

其实你的做法是对的。但是您将 MouseMove 属性赋予了图片框。您应该将该属性赋予 Form(background)。

ex:

前任:

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