Move controls when Drag and drop on panel in C#

0 votes
asked Mar 13, 2010 by dinu

I want to drag controls on panel and when dragging I want to move the control and get its location to drop on to panel. I have tried out mouseUp, mouseDown, MouseMove events of control.But that is not what I am looking for. I want to fire DragDrop event on panel and move control. Can I do this? If you can give me an idea it will be great. Below is part of my code. Please correct me. Thanks a lot.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DragnDrop
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }
        Control mycontrol;
        int x, y;
        //Form1 f = new Form1();
        private void Form1_Load(object sender, EventArgs e)
        {

            foreach (Control c in this.panel1.Controls)
            {
                c.MouseMove += new MouseEventHandler(lblDragger_MouseMove);
                c.MouseUp += new MouseEventHandler(lblDragger_MouseUp);
                c.MouseDown += new MouseEventHandler(pictureBox1_MouseDown);
                c.MouseDoubleClick += new MouseEventHandler(pictureBox1_MouseDown);
            }
            panel2.AllowDrop = true;
            foreach (Control c in this.panel2.Controls)
            {
                c.MouseDown += new MouseEventHandler(pictureBox1_MouseDown);
            }
            panel2.DragOver += new DragEventHandler(panel2_DragOver);
            panel2.DragDrop += new DragEventHandler(panel2_DragDrop);  
        }

        bool isDragging ;
        int  clickOffsetX ;
        int  clickOffsetY ;

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            //  this.Cursor = Cursors.SizeAll;
            //pictureBox1 = (PictureBox)sender;
            Control c = sender as Control;

            //DoDragDrop(pictureBox1.Image, DragDropEffects.Copy);
            // validation = true;
            isDragging = true;
            clickOffsetX = e.X;
            clickOffsetY = e.Y;
            //  c.DoDragDrop(c, DragDropEffects.Move);  
        }

        private void lblDragger_MouseUp(System.Object sender, System.Windows.Forms.MouseEventArgs e)
        {
            isDragging = false;
        }

        private void panel2_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(Bitmap)))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void panel2_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;  
        }

        private void panel2_DragDrop(object sender, DragEventArgs e)
        {
            Control c = e.Data.GetData(e.Data.GetFormats()[0]) as Control;
            mycontrol = c;
            if (c != null)
            {
                c.Location = this.panel2.PointToClient(new Point(e.X, e.Y));
                this.panel2.Controls.Add(c);
            }  
        }

        private void lblDragger_MouseMove(System.Object sender,
          System.Windows.Forms.MouseEventArgs e)
        {
            Control c = sender as Control;
            // bool isDragging = true;
            if (isDragging == true)
            {
                c.Left = e.X + c.Left - clickOffsetX;
                c.Top = e.Y + c.Top - clickOffsetY;
            }
        }

        private void panel1_MouseLeave(object sender, EventArgs e)
        {
            Control c = sender as Control;

            c.DoDragDrop(c, DragDropEffects.Move); 
        }
    }
}

3 Answers

0 votes
answered Mar 13, 2010 by dan-bryant

If your control is already on the panel and you're simply moving it within the same panel, then using the Mouse events is probably the easiest way to do this. My understanding is that Drag and Drop is more about conveying data between controls or even applications. Drag and drop would be a good fit if you're trying to allow a control to transfer between panels, for example.


If you want to do both, then here's one possible idea:

  1. Perform move dragging within the same panel using your Mouse events.

  2. When you get a MouseLeave event on the panel, begin a DragDrop operation (some examples here) You can either remove the control from the panel or add some sort of 'gray out' effect to indicate that the control may be leaving.

  3. Handle the DragDrop on your target panel and place the control at the mouse location of the drop.

This combines the intuitive feel of dragging the control around, while also providing a way to drag 'past' the panel and on to a new surface.

0 votes
answered Mar 13, 2010 by payton-byrd

You will need to use the mouse up and mouse down events to toggle your drag state. When you go mouse down, you start dragging. You record the relative position of the mouse within your control and the relative position of your control within the panel. You then follow the mouse as it moves and repositioning the control's top and left relative to the original location of the mouse within your control.

0 votes
answered Mar 2, 2011 by davide-piras

This is a complete example on how to host the Form Designer:

Tailor Your Application by Building a Custom Forms Designer with .NET, MSDN Magazine 2004 December ed.

I did something similar in Delphi long time ago, will search the source code, convert it into .NET C# and make a wiki page on that matter, as it is becoming such popular question recently :)

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...