Click here to Skip to main content
Click here to Skip to main content

Drag and Drop Windows/Form Controls (Design UI at Runtime)

, 13 Sep 2007 CPOL
Rate this:
Please Sign up or sign in to vote.
Enables user to design the user interface by moving all form controls to the desired place. It allows to move the control at execution time.
Screenshot - movableControls.jpg

Introduction

The source code of this article allows the user to provide a kind of user interface in which controls can be dragged and dropped on a form at the desired place. Clicking on Design Mode will enable the user to move all form controls by just clicking the mouse left button and dropping the control by leaving the mouse control. The good thing is that to enable the runtime dragging capability, there is no need to change the main form class or classes of controls. Everything is controlled using a separate class that has a small interface with the main form class.

Background

This article is totally based on Windows controls, mouse events, paint events and update regions.

Using the Code

A separate user control (draggableControls) is implemented. Just drag and drop that control on the Main Form from the toolbox. It would be invisible at runtime. This class has a DesignMode function that enables and disables runtime movement of all form controls by registering and unregistering event handlers of Mouse events. Look at the function given below, it is fully commented.

//
public void DesignMode(bool Enable)
{
mainForm = TopLevelControl; //Take the handle of main form control
Control ctrl = mainForm.GetNextControl(null, true); //Get First Control
do
{ 
if(ctrl.Text!="Design Mode" && ctrl.Text!="Control Mode") //Leave two buttons
SetEvent(ctrl, Enable); // Register/Unregister Event Handler
ctrl = mainForm.GetNextControl(ctrl, true); //Get Next Control
}while( ctrl != null); 
if (Enable) //Register/Unregister main form paint events
{
mainForm.Paint += new PaintEventHandler(mainForm_Paint);
mainForm.MouseMove += new MouseEventHandler(mainForm_MouseMove);
mainForm.MouseUp += new MouseEventHandler(mainForm_MouseUp);
}else
{
mainForm.Paint -= new PaintEventHandler(mainForm_Paint);
mainForm.MouseMove -= new MouseEventHandler(mainForm_MouseMove);
mainForm.MouseUp -= new MouseEventHandler(mainForm_MouseUp);
}
}
//

Other important functions are mouse Events (up, down, move) and main form Paint Event. On the mouse down event, we store the control and control size. On the mouse move event, it shows the dummy image of the control and on mouse down, it places the control at that place.

In the OnPaint function, it shows the dummy image of the control. To stop flickering and to optimize graphics, it creates the control path and updates only the dummy image path.

The code of these functions are given below:

void ctrl_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//find out which control is being dragged
controlUnderDrag = mainForm.GetChildAtPoint(((Control)sender).Location + 
    new Size(e.Location.X, e.Location.Y));
if (controlUnderDrag != null)
{
mainForm.Capture = true; //capture mouse
mainForm.Cursor = Cursors.Hand; //change cursor
controlImage = new Rectangle(controlUnderDrag.Location, controlUnderDrag.Size);
//offset of mouse from control location
mouseOffset = new Size(e.Location.X, e.Location.Y); 
Rectangle tempRectangle = new Rectangle(controlImage.X - 2, 
    controlImage.Y - 2, controlImage.Width + 4, controlImage.Height + 4);
GraphicsPath myGraphicsPath = new GraphicsPath(); //path of rectangle area of control
myGraphicsPath.AddRectangle(tempRectangle);
System.Drawing.Region rgn = new Region(myGraphicsPath);
mainForm.Invalidate(rgn);
controlDragStarted = true;
} 
}
}
void mainForm_MouseMove(object sender, MouseEventArgs e)
{
if (controlDragStarted)
{
GraphicsPath myGraphicsPath = new GraphicsPath();
Rectangle tempRectangle = new Rectangle(controlImage.X - 2, controlImage.Y - 2, 
    controlImage.Width + 4, controlImage.Height + 4);
myGraphicsPath.AddRectangle(tempRectangle);
System.Drawing.Region rgn = new Region(myGraphicsPath);
controlImage = new Rectangle(e.Location.X - mouseOffset.Width, 
    e.Location.Y - mouseOffset.Height, controlImage.Width,
controlImage.Height);

mainForm.Invalidate(rgn);
myGraphicsPath.Dispose();
myGraphicsPath = new GraphicsPath();
rgn.Dispose();
tempRectangle = new Rectangle(controlImage.X - 2, controlImage.Y - 2, 
    controlImage.Width + 4, controlImage.Height + 4);
rgn = new Region(tempRectangle);
mainForm.Invalidate(rgn);
 }
}
void mainForm_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && controlDragStarted)
{
controlDragStarted = false;
mainForm.Capture = false;
mainForm.Cursor = Cursors.Default;
GraphicsPath myGraphicsPath = new GraphicsPath();
Rectangle tempRectangle = new Rectangle(controlImage.X - 2, controlImage.Y - 2, 
    controlImage.Width + 4, controlImage.Height + 4);
myGraphicsPath.AddRectangle(tempRectangle);
System.Drawing.Region rgn = new Region(myGraphicsPath);
controlUnderDrag.Location = controlImage.Location;
controlImage.Height = 0; controlImage.Width = 0;
mainForm.Invalidate(rgn);
controlUnderDrag.Invalidate();
}
}
void mainForm_Paint(object sender, PaintEventArgs e)
{ 
if (controlImage != null && controlDragStarted)
{
e.Graphics.DrawRectangle(Pens.Green, controlImage);
}
}

Further Enhancements

Further enhancements like allowing to move only the selected controls, showing a different color dummy image while the control is moving can be done easily just by adding some properties in the DraggableControls class.

History

  • 14th September, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

vikas maan
Software Developer (Senior)
India India
Vikas Maan is a software developer for last 4 years working on windows platform with multiple programming languages mainly VC++, C#.net etc.

Comments and Discussions

 
GeneralMDI Child Object Access Problem Pinmemberhakcay1-Jun-10 0:44 
GeneralDragg Multiple Control Pinmemberjazzyvishal12-Sep-08 1:00 
GeneralRe: Dragg Multiple Control Pinmembervikas maan24-Sep-08 18:56 
GeneralProblem Using with MDI PinmemberMember 369598819-May-08 4:58 
GeneralRe: Problem Using with MDI PinmemberMember 301963930-May-08 8:14 
GeneralRe: Problem Using with MDI Pinmembertarikcorut11-Aug-09 4:22 
QuestionQuestion... dragging controls on a TabControl/TabPage PinmemberGary Butler6-Dec-07 10:20 
GeneralRe: Question... dragging controls on a TabControl/TabPage Pinmembervikas maan8-Jan-08 19:42 
QuestionRemember Last Setting Pinmemberprit_mahudha16-Oct-07 1:38 
AnswerRe: Remember Last Setting Pinmembervikas maan16-Oct-07 18:35 
GeneralRe: Remember Last Setting Pinmemberprit_mahudha16-Oct-07 22:44 
GeneralRe: Remember Last Setting Pinmembervikas maan8-Jan-08 19:45 
GeneralCustom Designer PinmemberDan Radu18-Sep-07 4:50 
GeneralRe: Custom Designer Pinmembervikas maan19-Sep-07 19:03 
GeneralNice try PinmemberNinethSense16-Sep-07 22:05 
GeneralRe: Nice try Pinmembervikas maan19-Sep-07 19:03 
GeneralInteresting Idea Pinmembermerlin98114-Sep-07 6:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 14 Sep 2007
Article Copyright 2007 by vikas maan
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid