Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

Draggable WinForms Controls

4.98/5 (56 votes)
8 Apr 2011CPOL 98.8K  
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)