Search code examples
c#winformsmouseeventdraggable

C# drag controls around a panel


i am developing a system which allow user to drag objects around within a same panel, i went through some research and founds that i should use mouse events like mouse_up, mouse_down and mouse_move.

The the program will generate 3 picturebox and allow the user to drag around the every picturebox within the panel, but the program i code did not work perfectly as when i drag over a picturebox, the picturebox will move, but not according to my mouse cursor location, it is somewhere else, besides, when dragging, there is picturebox shadows in the panel, i've tried those update(),refresh(), and invalidate() but it seems not useful for me. Below are my codes, thanks for helping

public partial class Form1 : Form
{

    List<PictureBox> pictureBoxList = new List<PictureBox>();
    private bool isDragging = false;

    public Form1()
    {
        InitializeComponent();

        for (int i = 0; i < 3; i++)
        {
            PictureBox picture = new PictureBox
            {
                Name = "pictureBox" + i,
                Size = new Size(20, 20),
                Location = new Point(i * 40, i * 40),
                BorderStyle = BorderStyle.FixedSingle,
                SizeMode = PictureBoxSizeMode.Zoom,
                ImageLocation = "A.jpg"
            };
            pictureBoxList.Add(picture);


            foreach (PictureBox p in pictureBoxList)
            {
                p.MouseDown += new MouseEventHandler(c_MouseDown);
                p.MouseMove += new MouseEventHandler(c_MouseMove);
                p.MouseUp += new MouseEventHandler(c_MouseUp);
                pnlDisplayImage.Controls.Add(p);
                pnlDisplayImage.Refresh();
            }
        }
    }


    void c_MouseDown(object sender, MouseEventArgs e)
    {
        isDragging = true;
    }

    void c_MouseMove(object sender, MouseEventArgs e)
    {

        if (isDragging == true) {
            Control c = sender as Control;
            for (int i = 0; i < pictureBoxList.Count(); i++)
            {
                if (c.Equals(pictureBoxList[i]))
                {
                    pictureBoxList[i].Location = new Point(e.X, e.Y);
                }
            }
        }
    }

    void c_MouseUp(object sender, MouseEventArgs e)
    {
        PictureBox c = sender as PictureBox;
        isDragging = false;
        for (int i = 0; i < pictureBoxList.Count(); i++) { 
            if (c.Equals(pictureBoxList[i])){
                pictureBoxList[i].Location = new Point(e.X, e.Y);
            }
        }
    }

    private void pnlDisplayImage_Paint(object sender, PaintEventArgs e)
    {
        foreach (PictureBox p in pictureBoxList)
        {
            pnlDisplayImage.Controls.Add(p);
        }
    }

}

Solution

  • Finally I've found what are the problems that caused my program not running as my expectations. The main problem is that I accidentally put the foreach loop inside the for loop which I used to create pictureBox, this problem caused the pictureBox comes out some shadows effect while dragging during run time due to there are few same pictureBox. Also, I have change a little bit of the codes and it now run as what I expected. Below are the code that I want for answer.

    public partial class Form1 : Form
    {
    
        List<PictureBox> pictureBoxList = new List<PictureBox>();
        private bool isDragging = false;
        Point move;
    
        public Form1()
        {
            InitializeComponent();
    
            for (int i = 0; i < 3; i++)
            {
                PictureBox picture = new PictureBox
                {
                    Name = "pictureBox" + i,
                    Size = new Size(20, 20),
                    Location = new Point(i * 40, i * 40),
                    BorderStyle = BorderStyle.FixedSingle,
                    SizeMode = PictureBoxSizeMode.Zoom,
                    ImageLocation = "A.jpg"
                };
                pictureBoxList.Add(picture);
            }
    
            foreach (PictureBox p in pictureBoxList)
            {
                    p.MouseDown += new MouseEventHandler(c_MouseDown);
                    p.MouseMove += new MouseEventHandler(c_MouseMove);
                    p.MouseUp += new MouseEventHandler(c_MouseUp);
                    pnlDisplayImage.Controls.Add(p);
                    pnlDisplayImage.Refresh();
             }
    
        }
    
        void c_MouseDown(object sender, MouseEventArgs e)
        {
            Control c = sender as Control;
            isDragging = true;
            move = e.Location;
        }
    
        void c_MouseMove(object sender, MouseEventArgs e)
        {
    
            if (isDragging == true) {
                Control c = sender as Control;
                for (int i = 0; i < pictureBoxList.Count(); i++)
                {
                    if (c.Equals(pictureBoxList[i]))
                    {
                        pictureBoxList[i].Left += e.X - move.X;
                        pictureBoxList[i].Top += e.Y - move.Y;
                    }
                }
            }
        }
    
        void c_MouseUp(object sender, MouseEventArgs e)
        {
            isDragging = false;
        }
    }