Move a PictureBox with mouse

27,696

Solution 1

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) .

The values for imagenMapa.Left and imagenMapa.Top are relative to the form (or whatever control contains 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.

Note that depending on your needs, you could accomplish "moving an image within a control" by overriding/handling the Paint event of 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.

Solution 2

Actual Code (Requires .NET Framework 3.5 and beyond, not sure if this is available in the 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;
};

Solution 3

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

Solution 4

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

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

Solution 5

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).

ex:

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
  imagenMapa.Left = e.X;
  imagenMapa.Top = e.Y;
}
Share:
27,696
VansFannel
Author by

VansFannel

I'm software architect, entrepreneur and self-taught passionate with new technologies. At this moment I am studying a master's degree in advanced artificial intelligence and (in my free time ) I'm developing an immersive VR application with Unreal Engine. I have also interested in home automation applying what I'm learning with Udacity's nanodegree course in object and voice recognition.

Updated on December 14, 2020

Comments

  • VansFannel
    VansFannel over 3 years

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

    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.

    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.

    What I'm doing wrong?

  • VansFannel
    VansFannel about 15 years
    I'm using Compact Framework and Forms doesn't have double buffer. How can I do this?
  • Alex Gordon
    Alex Gordon almost 15 years
    daniel this is nice theory but can you put it into code please? i have the same exact question but in VB.net. please help!
  • saurabhj
    saurabhj over 10 years
    This works flawlessly! Thank you for taking the time to share code :)