Click here to Skip to main content
15,882,113 members
Articles / Desktop Programming / Windows Forms
Tip/Trick

Draggable WinForms Controls

Rate me:
Please Sign up or sign in to vote.
4.98/5 (55 votes)
8 Apr 2011CPOL 93.3K   41   31
Extension method to make any WinForms control to be draggable at runtime

Sometimes, you need to make the control draggable during runtime. It can be a form with FormBorderStyle property set to None, or any other situation. I want to propose a simple extension method that allows you to make this possible.

C#
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace DraggableControls
{
    public static class ControlExtension
    {
        // TKey is control to drag, TValue is a flag used while dragging
        private static Dictionary<Control, bool> draggables = 
                   new Dictionary<Control, bool>();
        private static System.Drawing.Size mouseOffset;
 
        /// <summary>
        /// Enabling/disabling dragging for control
        /// </summary>
        public static void Draggable(this Control control, bool Enable)
        {
            if (Enable)
            {
                // enable drag feature
                if (draggables.ContainsKey(control))
                {   // return if control is already draggable
                    return;
                }
                // 'false' - initial state is 'not dragging'
                draggables.Add(control, false);
 
                // assign required event handlersnnn
                control.MouseDown += new MouseEventHandler(control_MouseDown);
                control.MouseUp += new MouseEventHandler(control_MouseUp);
                control.MouseMove += new MouseEventHandler(control_MouseMove);
            }
            else
            {
                // disable drag feature
                if (!draggables.ContainsKey(control))
                {  // return if control is not draggable
                    return;
                }
                // remove event handlers
                control.MouseDown -= control_MouseDown;
                control.MouseUp -= control_MouseUp;
                control.MouseMove -= control_MouseMove;
                draggables.Remove(control);
            }
        }
        static void control_MouseDown(object sender, MouseEventArgs e)
        {
            mouseOffset = new System.Drawing.Size(e.Location);
            // turning on dragging
            draggables[(Control)sender] = true;
        }
        static void control_MouseUp(object sender, MouseEventArgs e)
        {
            // turning off dragging
            draggables[(Control)sender] = false;
        }
        static void control_MouseMove(object sender, MouseEventArgs e)
        {
            // only if dragging is turned on
            if (draggables[(Control)sender] == true)
            {
                // calculations of control's new position
                System.Drawing.Point newLocationOffset = e.Location - mouseOffset;
                ((Control)sender).Left += newLocationOffset.X;
                ((Control)sender).Top += newLocationOffset.Y;
            }
        }
    }
}

It's pretty simple to use this code. To make control draggable, you just need to write one line of code:

C#
AnyControl.Draggable(true);

and to disable this feature:

C#
AnyControl.Draggable(false);

For example, if your Form contains two checkboxes named checkBox_DragForm and checkBox_DragButton with CheckedChanged event handlers assigned, and button with name btnTest, you may use the following code to enable/disable drag feature on Form (represented by this) or/and button:

C#
private void checkBox_DragForm_CheckedChanged(object sender, EventArgs e)
{
    this.Draggable(checkBox_DragForm.Checked);
}
private void checkBox_DragButton_CheckedChanged(object sender, EventArgs e)
{
    btnTest.Draggable(checkBox_DragButton.Checked);
}

Update (2015-02-26): Extention is also available on Github and as a Nuget package

License

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


Written By
Software Developer DevelopEx
Ukraine Ukraine
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
SuggestionThanks for this simple and nice solution - I added a small feature to keep the control within boundaries of parent Pin
MightyMart22-Jan-20 14:24
MightyMart22-Jan-20 14:24 
GeneralMy vote of 5 Pin
csharpbd23-Dec-19 8:51
professionalcsharpbd23-Dec-19 8:51 
QuestionUsing with Custom Control Pin
Member 1401938010-Dec-18 16:46
Member 1401938010-Dec-18 16:46 
AnswerRe: Using with Custom Control Pin
Member 1554145624-Feb-22 14:01
Member 1554145624-Feb-22 14:01 
QuestionIntegration problem and how I solved it Pin
RCStrange7-May-17 23:50
RCStrange7-May-17 23:50 
QuestionAfter I add it for a User Control in Flow Layout Panel. It can't normal draw Pin
qakmak3-Sep-15 7:04
qakmak3-Sep-15 7:04 
QuestionClick Event Pin
Manvendra Singh23-Feb-15 19:38
Manvendra Singh23-Feb-15 19:38 
AnswerRe: Click Event Pin
intrueder25-Feb-15 23:10
intrueder25-Feb-15 23:10 
GeneralRe: Click Event Pin
Manvendra Singh25-Feb-15 23:57
Manvendra Singh25-Feb-15 23:57 
AnswerRe: Click Event Pin
intrueder26-Feb-15 2:42
intrueder26-Feb-15 2:42 
GeneralRe: Click Event Pin
Manvendra Singh26-Feb-15 18:07
Manvendra Singh26-Feb-15 18:07 
GeneralMy vote of 5 Pin
nirav raval13-Feb-15 1:09
professionalnirav raval13-Feb-15 1:09 
AnswerRe: My vote of 5 Pin
intrueder26-Feb-15 7:32
intrueder26-Feb-15 7:32 
GeneralMy vote of 5 Pin
Erik Norman9-Feb-15 3:20
Erik Norman9-Feb-15 3:20 
GeneralMy vote of 5 Pin
Keyi Zhang12-Jul-13 23:12
Keyi Zhang12-Jul-13 23:12 
GeneralMy vote of 5 Pin
Horseman270323-Jan-13 22:18
Horseman270323-Jan-13 22:18 
AnswerRe: My vote of 5 Pin
intrueder23-Jan-13 23:55
intrueder23-Jan-13 23:55 
GeneralMy vote of 5 Pin
LeszekCode27025-Oct-12 21:24
LeszekCode27025-Oct-12 21:24 
GeneralMy vote of 5 Pin
truongvu_12324-Jun-12 23:20
truongvu_12324-Jun-12 23:20 
GeneralReason for my vote of 5 easy to use Pin
CalvinWang18-Dec-11 23:17
CalvinWang18-Dec-11 23:17 
GeneralReason for my vote of 5 Very nice. Thanks Pin
zenwalker198518-Dec-11 23:15
zenwalker198518-Dec-11 23:15 
GeneralReason for my vote of 5 Excellent!! thank you very much..it... Pin
jawed.ace27-Jun-11 23:01
jawed.ace27-Jun-11 23:01 
GeneralReason for my vote of 5 Nice one..thanks!! Pin
jawed.ace25-Jun-11 21:23
jawed.ace25-Jun-11 21:23 
GeneralRe: thanks for your vote! Pin
intrueder26-Jun-11 4:02
intrueder26-Jun-11 4:02 
Generalwow! I like it Pin
zhanghaocol1-May-11 22:44
zhanghaocol1-May-11 22:44 

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

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