Click here to Skip to main content
Click here to Skip to main content
Go to top

The Dragable Container

, 10 Nov 2008
Rate this:
Please Sign up or sign in to vote.
How to create and use a dragable container at runtime.

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:

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

Share

About the Author

Dariush Tasdighi
Web Developer
Iran (Islamic Republic Of) Iran (Islamic Republic Of)
I'm experienced in below items:
 
- XML 1.0
- CSS 2.0
- ASP 3.0
- HTML 4.01
- XHTML 1.0
- Javascript 1.5
- .NET Framework 1.1/2.0
- Microsoft Office 2000/XP
- Microsoft Visual Basic 6
- Microsoft SQL Server 2000/2005
- Microsoft C#.NET (Windows Based)
- Microsoft C#.NET (XML Web Service)
- Microsoft C#.NET (Web Based = ASP.NET)
 
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 PinmemberHamed Almighty28-Jan-12 5:31 
Generalplz help Pinmemberqauaan13-Sep-09 6:44 
GeneralNice article! PinmemberMolestoMalo3-Dec-08 10:21 
GeneralDragging PinmemberSilvyster17-Nov-08 12:23 
GeneralC# 2005 PinmemberMOISJWang17-Nov-08 5:31 
GeneralRe: C# 2005 PinmemberSilvyster17-Nov-08 12:18 

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 | Mobile
Web04 | 2.8.140916.1 | Last Updated 10 Nov 2008
Article Copyright 2008 by Dariush Tasdighi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid