Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / Windows Forms
Article

The Dragable Container

Rate me:
Please Sign up or sign in to vote.
4.95/5 (14 votes)
10 Nov 2008MIT 35.9K   764   42   6
How to create and use a dragable container at runtime.

Image 1

Introduction

This class was designed with some of the most important patterns like the Singleton Pattern and the Decorator Pattern. With this class (DragableContainer), you can move and resize all of your controls at runtime. This class is suitable for anybody wanting to create applications such as a Form Generator, Report Generator, Form Customization, and so forth... I hope this class will be useful for you and your application. Please tell me whatever you think about and notify me of bugs, so can I try to improve this class as much as possible.

Using the code

You can see the DragableClass in below. By the way, you can download the zip file to get the source code and the sample. Getting the sample is useful for you so that you can learn how to use this class in your applications.

Here is the DragableClass source code:

C#
namespace Dtx.Windows.Forms
{
    [System.ComponentModel.Browsable(false)]
    [System.ComponentModel.DesignTimeVisible(false)]
    public class DragableContainer : System.Windows.Forms.Panel
    {
        // Begin: Singleton Pattern
        private static DragableContainer _instance;
        public static DragableContainer Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new DragableContainer();

                return (_instance);
            }
        }

        private DragableContainer()
        {
            Initialize();
        }
        // End: Singleton Pattern

        protected enum DragModes
        {
            None,
            TopLeft,
            TopRight,
            Top,
            BottomLeft,
            BottomRight,
            Bottom,
            Left,
            Right
        }

        private System.Windows.Forms.Control _myControl;
        protected System.Windows.Forms.Control MyControl
        {
            get
            {
                return (_myControl);
            }
            set
            {
                _myControl = value;

                if (value != null)
                {
                    _myControl.Resize += new System.EventHandler(MyControl_Resize);
                    _myControl.MouseEnter += 
                        new System.EventHandler(MyControl_MouseEnter);
                }
            }
        }

        private System.Windows.Forms.AnchorStyles _myControlAnchorStyles;
        protected System.Windows.Forms.AnchorStyles MyControlAnchorStyles
        {
            get
            {
                return (_myControlAnchorStyles);
            }
            set
            {
                _myControlAnchorStyles = value;
            }
        }

        protected virtual int Gap
        {
            get
            {
                return (1);
            }
        }

        private bool _isMouseDown;
        protected bool IsMouseDown
        {
            get
            {
                return (_isMouseDown);
            }
            set
            {
                _isMouseDown = value;
            }
        }

        private int _edgeSize;
        [System.ComponentModel.DefaultValue(4)]
        public virtual int EdgeSize
        {
            get
            {
                return (_edgeSize);
            }
            set
            {
                _edgeSize = value;
            }
        }

        private DragModes _dragMode;
        protected DragModes DragMode
        {
            get
            {
                return (_dragMode);
            }
            set
            {
                _dragMode = value;
            }
        }

        private System.Drawing.Pen _squarePen;
        protected System.Drawing.Pen SquarePen
        {
            get
            {
                if (_squarePen == null)
                    _squarePen = 
                      new System.Drawing.Pen(System.Drawing.Color.Black, 1);

                return (_squarePen);
            }
        }

        private System.Drawing.Brush _squareFillBrush;
        protected System.Drawing.Brush SquareFillBrush
        {
            get
            {
                if (_squareFillBrush == null)
                    _squareFillBrush = 
                      new System.Drawing.SolidBrush(System.Drawing.Color.White);

                return (_squareFillBrush);
            }
        }

        protected virtual void RefreshControl()
        {
            Refresh();
            Invalidate();
        }

        public virtual void SetControl(System.Windows.Forms.Control control)
        {
            if (MyControl == control)
                return;

            System.Windows.Forms.Control ctlParent = null;

            if (MyControl != null)
            {
                ctlParent = Parent;

                MyControl.Top = Top + EdgeSize + Gap;
                MyControl.Left = Left + EdgeSize + Gap;
                MyControl.Width = Width - EdgeSize * 2 - Gap - 1;
                MyControl.Height = Height - EdgeSize * 2 - Gap - 1;

                Controls.Remove(MyControl);
                ctlParent.Controls.Add(MyControl);

                // It's too important to write this code here!
                // specially if the control is for [Label].
                MyControl.Anchor = MyControlAnchorStyles;
            }

            if (control == null)
            {
                if (ctlParent != null)
                {
                    MyControl = null;
                    ctlParent.Controls.Remove(this);
                }
            }
            else
            {
                MyControl = control;
                MyControlAnchorStyles = MyControl.Anchor;
                MyControl.Anchor =
                    System.Windows.Forms.AnchorStyles.Top |
                    System.Windows.Forms.AnchorStyles.Left |
                    System.Windows.Forms.AnchorStyles.Right |
                    System.Windows.Forms.AnchorStyles.Bottom;

                Top = control.Top - EdgeSize - Gap;
                Left = control.Left - EdgeSize - Gap;
                Width = MyControl.Width + EdgeSize * 2 + Gap + 1;
                Height = MyControl.Height + EdgeSize * 2 + Gap + 1;

                ctlParent = control.Parent;

                ctlParent.Controls.Remove(MyControl);
                MyControl.Top = EdgeSize + Gap;
                MyControl.Left = EdgeSize + Gap;
                Controls.Add(MyControl);
                ctlParent.Controls.Add(this);
            }

            Initialize();
        }

        protected virtual void Initialize()
        {
            EdgeSize = 4;
            IsMouseDown = false;
            DragMode = DragModes.None;

            RefreshControl();
        }

        protected void MyControl_Resize(object sender, System.EventArgs e)
        {
            if (Width != MyControl.Width + EdgeSize * 2 + Gap + 1)
                Width = MyControl.Width + EdgeSize * 2 + Gap + 1;

            if (Height != MyControl.Height + EdgeSize * 2 + Gap + 1)
                Height = MyControl.Height + EdgeSize * 2 + Gap + 1;
        }

        protected virtual void MyControl_MouseEnter(object sender, System.EventArgs e)
        {
            // Node
            DragMode = DragModes.None;
            Cursor = System.Windows.Forms.Cursors.Default;

            RefreshControl();
        }

        protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseDown(e);

            // If we are in design mode (not in runtime mode) do nothing.
            if (DesignMode)
                return;

            if (e.Button == System.Windows.Forms.MouseButtons.Left)
                IsMouseDown = true;
        }

        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // If we are in design mode (not in runtime mode) do nothing.
            if (DesignMode)
                return;

            if ((IsMouseDown) && (DragMode != DragModes.None))
            {
                SuspendLayout();

                switch (DragMode)
                {
                    case DragModes.TopLeft:
                    {
                        //SetBounds(Left + e.X, Top + e.Y, Width, Height); // Original
                        SetBounds(Left + e.X - EdgeSize, 
                                  Top + e.Y - EdgeSize, Width, Height);
                        break;
                    }

                    case DragModes.TopRight:
                    {
                        SetBounds(Left, Top + e.Y, e.X + EdgeSize, Height - e.Y);
                        break;
                    }

                    case DragModes.Top:
                    {
                        SetBounds(Left, Top + e.Y, Width, Height - e.Y);
                        break;
                    }

                    case DragModes.BottomLeft:
                    {
                        SetBounds(Left + e.X, Top, Width - e.X, e.Y + EdgeSize);
                        break;
                    }

                    case DragModes.BottomRight:
                    {
                        SetBounds(Left, Top, e.X + EdgeSize, e.Y + EdgeSize);
                        break;
                    }

                    case DragModes.Bottom:
                    {
                        // SetBounds(Left, Top, Width, e.Y); // Original
                        SetBounds(Left, Top, Width, e.Y + EdgeSize);
                        break;
                    }

                    case DragModes.Left:
                    {
                        SetBounds(Left + e.X, Top, Width - e.X, Height);
                        break;
                    }

                    case DragModes.Right:
                    {
                        //SetBounds(Left, Top, e.X, Height); // Original
                        SetBounds(Left, Top, e.X + EdgeSize, Height);
                        break;
                    }
                }

                ResumeLayout();
            }
            else
            {
                // Top Left
                if ((e.Y <= EdgeSize * 2) && (e.X <= EdgeSize * 2))
                {
                    DragMode = DragModes.TopLeft;
                    Cursor = System.Windows.Forms.Cursors.SizeAll;
                    RefreshControl();
                    return;
                }

                // Top Right
                if ((e.Y <= EdgeSize) && (e.X >= Width - EdgeSize))
                {
                    DragMode = DragModes.TopRight;
                    Cursor = System.Windows.Forms.Cursors.SizeNESW;
                    RefreshControl();
                    return;
                }

                // Top
                if (e.Y <= EdgeSize)
                {
                    DragMode = DragModes.Top;
                    Cursor = System.Windows.Forms.Cursors.SizeNS;
                    RefreshControl();
                    return;
                }

                // Bottom Left
                if ((e.Y >= Height - EdgeSize) && (e.X <= EdgeSize))
                {
                    DragMode = DragModes.BottomLeft;
                    Cursor = System.Windows.Forms.Cursors.SizeNESW;
                    RefreshControl();
                    return;
                }

                // Bottom Right
                if ((e.Y >= Height - EdgeSize) && (e.X >= Width - EdgeSize))
                {
                    DragMode = DragModes.BottomRight;
                    Cursor = System.Windows.Forms.Cursors.SizeNWSE;
                    RefreshControl();
                    return;
                }

                // Bottom
                if (e.Y >= Height - EdgeSize)
                {
                    DragMode = DragModes.Bottom;
                    Cursor = System.Windows.Forms.Cursors.SizeNS;
                    RefreshControl();
                    return;
                }

                // Left
                if (e.X <= EdgeSize)
                {
                    DragMode = DragModes.Left;
                    Cursor = System.Windows.Forms.Cursors.SizeWE;
                    RefreshControl();
                    return;
                }

                // Right
                if (e.X >= Width - EdgeSize)
                {
                    DragMode = DragModes.Right;
                    Cursor = System.Windows.Forms.Cursors.SizeWE;
                    RefreshControl();
                    return;
                }

                // Node
                DragMode = DragModes.None;
                Cursor = System.Windows.Forms.Cursors.Default;
            }

            RefreshControl();
        }

        protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseUp(e);

            // If we are in design mode (not in runtime mode) do nothing.
            if (DesignMode)
                return;

            IsMouseDown = false;
            DragMode = DragModes.None;

            RefreshControl();
        }

        protected override void OnMouseLeave(System.EventArgs e)
        {
            base.OnMouseLeave(e);

            // If we are in design mode (not in runtime mode) do nothing.
            if (DesignMode)
                return;

            IsMouseDown = false;
            DragMode = DragModes.None;

            RefreshControl();
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaint(e);

            // If we are in design mode (not in runtime mode) do nothing.
            if (DesignMode)
                return;

            int intTop;
            int intLeft;

            int intSquareWidth = EdgeSize;
            int intSquareHeight = EdgeSize;

            int intSquareFillWidth = EdgeSize - 1;
            int intSquareFillHeight = EdgeSize - 1;

            System.Drawing.Graphics oGraphics = e.Graphics;

            // Draw Square in [Top Left]
            intTop = 0;
            intLeft = 0;
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, 
                                    intTop + 1, intSquareFillWidth, 
                                    intSquareFillHeight);

            // Draw Square in [Top Middle]
            intTop = 0;
            intLeft = (Width - EdgeSize) / 2 + (EdgeSize / 2);
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, intTop + 1, 
                                    intSquareFillWidth, intSquareFillHeight);

            // Draw Square in [Top Right]
            intTop = 0;
            intLeft = Width - EdgeSize - 1;
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, intTop + 1, 
                                    intSquareFillWidth, intSquareFillHeight);

            // Draw Square in [Middle Left]
            intTop = (Height - EdgeSize) / 2;
            intLeft = 0;
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, intTop + 1, 
                                    intSquareFillWidth, intSquareFillHeight);

            // Draw Square in [Middle Right]
            intTop = (Height - EdgeSize) / 2;
            intLeft = Width - EdgeSize - 1;
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, intTop + 1, 
                                    intSquareFillWidth, intSquareFillHeight);

            // Draw Square in [Bottom Left]
            intTop = Height - EdgeSize - 1;
            intLeft = 0;
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, intTop + 1, 
                                    intSquareFillWidth, intSquareFillHeight);

            // Draw Square in [Bottom Middle]
            intTop = Height - EdgeSize - 1;
            intLeft = (Width - EdgeSize) / 2 + (EdgeSize / 2);
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, intTop + 1, 
                                    intSquareFillWidth, intSquareFillHeight);

            // Draw Square in [Bottom Right]
            intTop = Height - EdgeSize - 1;
            intLeft = Width - EdgeSize - 1;
            oGraphics.DrawRectangle(SquarePen, intLeft, intTop, 
                                    intSquareWidth, intSquareHeight);
            oGraphics.FillRectangle(SquareFillBrush, intLeft + 1, intTop + 1, 
                                    intSquareFillWidth, intSquareFillHeight);

            if (Width != MyControl.Width + EdgeSize * 2 + Gap + 1)
                Width = MyControl.Width + EdgeSize * 2 + Gap + 1;

            if (Height != MyControl.Height + EdgeSize * 2 + Gap + 1)
                Height = MyControl.Height + EdgeSize * 2 + Gap + 1;
        }
    }
}

Points of Interest

I have used this class in my Report Generator application.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Web Developer Sematec Ins.
Iran (Islamic Republic of) Iran (Islamic Republic of)
My experiences are:

HTML 5.0, CSS 3.0
JQuery, Angular JS, Bootstrap

MVC 5.0, WEB API, c#

My Site URLs:
http://www.IranianExperts.ir
http://www.IranianExperts.com

My Yahoo Group URL: http://groups.yahoo.com/group/iranianexperts

Mobile: 0098-912-108-7461
Address: Tehran, Tehran, Iran

Comments and Discussions

 
GeneralMy vote of 5 Pin
Hamed Almighty28-Jan-12 5:31
Hamed Almighty28-Jan-12 5:31 
Generalplz help Pin
qauaan13-Sep-09 6:44
qauaan13-Sep-09 6:44 
GeneralNice article! Pin
MolestoMalo3-Dec-08 10:21
MolestoMalo3-Dec-08 10:21 
GeneralDragging Pin
Silvyster17-Nov-08 12:23
Silvyster17-Nov-08 12:23 
GeneralC# 2005 Pin
MOISJWang17-Nov-08 5:31
MOISJWang17-Nov-08 5:31 
GeneralRe: C# 2005 Pin
Silvyster17-Nov-08 12:18
Silvyster17-Nov-08 12:18 

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.