简体   繁体   中英

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);
        }
    }

}

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;
    }
}

Try something like (it's custom control with overrides, but should be easy to convert to events):

    private bool _isMoved = false;  // true if move mode on
    private Point _pointMove = new Point(0);    // for moving

    protected override void OnMouseDown(MouseEventArgs e)
    {
        // if left button pressed
        if(e.Button == MouseButtons.Left) 
        {
            _pointMove.X = e.X;
            _pointMove.Y = e.Y;
            _isMoved = true;
            Cursor = Cursors.SizeAll;
            Capture = true;
        }
        base.OnMouseDown (e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        // if move mode on
        if(_isMoved) 
        {
            _isMoved = false;
            Cursor = Cursors.Default;
            Capture = false;
        }
        base.OnMouseUp (e);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // if move mode on
        if (_isMoved)
        {
            Left += e.X - _pointMove.X;
            Top += e.Y - _pointMove.Y;
        }
        base.OnMouseMove (e);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM