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
Move a PictureBox with mouse
提问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.X
and e.Y
are relative to the picture box (e.g. if the mouse is in the upper left of the picture box, that's 0,0) .
的e.X
和e.Y
可相对于图像框(例如,如果鼠标在左上图片框,这就是0,0)。
The values for imagenMapa.Left
and imagenMapa.Top
are relative to the form (or whatever control contains imagenMapa
)
对值imagenMapa.Left
和imagenMapa.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.PointToScreen
to get the mouse coordinates in screen coordinates (or Cursor.Position
to get the position directly), and yourForm.PointToClient
to 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 Paint
eventof 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;
}