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

Runtime Editable Control

, 5 Dec 2004
Rate this:
Please Sign up or sign in to vote.
Inheritable (super class) UserForm that enables runtime moving of controls (editing).

Note

This is a simple example developed with VS.NET 2005 Beta 1 codename Whidbey. So, project and solution are not usable with previous versions, while code should run in previous versions without problems.

Introduction and background

Faced with and, as the matter of fact, astonished by user requirement specification for one project, where one of the requirements were that controls (some or all) on the form must be movable (runtime editable in narrower sense).

So after "brainstorming", the decision was made to make a framework to implement a UserControl for runtime movable controls called EditableControl. EditableControl should be super class for any custom made control with arbitrary number and type of controls.

The idea is to allow users to adjust his/hers look and feel through positions of controls, whereby business logic behind the control stays the same (actually, user is not able to change anything except presentation).

The control should be reusable, so it inherits from UserControl, and any other business logic control that inherits from EditableControl will be editable too.

Original control

Sample Image - Custom control before runtime layout editing

Control after runtime "editing"

Sample Image - Custom control after runtime layout editing

Design

EditableControl has four member variables for layout editing (moving): points for the origin of the moved control, destination, reference to control being moved, and an ArrayList of controls that can be moved (for other controls).

        /// <summary>
        /// Point where from Control will be moved
        /// </summary>
        private
            Point
            _point_begin 
            ;

        /// <summary>
        /// Point where to Control will be moved
        /// </summary>
        private
            Point
            _point_end
            ;

        /// <summary>
        /// Moved Control
        /// </summary>
        private
            Control
            _control_moving
            = null
            ;

        /// <summary>
        /// Container for defining set of movable/editable Controls
        /// <summary>
        public
            System.Collections.ArrayList
            EditableControls
            ;

To accomplish drag&drop of the control, three mouse events must be handled by containing (hosting control, parent) as well as by every contained (child) control. Those events are: MouseDown to detect selection of the control, MouseMove to animate movement, and MouseUp to detect destination point. Actually, only two events are needed: MouseDown and MouseUp, but animation can't hurt. Initialization hooks events to all contained child controls.

        /// <summary>
        /// initialize member function hooks mouse events of all child 
        /// controls to mouse event handlers of the EditableControl
        /// </summary>
        protected
            virtual
            void
            initialize
            (
            )
        {
            foreach (Control ctrl in Controls)
            {
                ctrl.MouseDown += new MouseEventHandler(MouseDownEventHandler);
                ctrl.MouseUp += new MouseEventHandler(MouseUpEventHandler);
                ctrl.MouseMove += new MouseEventHandler(MouseMoveEventHandler);
            }

            return;
        }

And events which are handled for each movable control and do not interfere with control's behavior (events and logic):

        /// <summary>
        /// MouseDownEventHandler detects whether child control was hit and
        /// sets the starting point for the move of the child control
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="evnt_args_mouse">
        /// </param>
        protected
            virtual
            void
            MouseDownEventHandler
            (
              object sender
            , MouseEventArgs evnt_args_mouse
            )
        {
            int x;
            int y;
            if (
                // while left button pressed (could define other keys)
                evnt_args_mouse.Button == MouseButtons.Left
                &&
                // ignore containing (parent) control
                ! "Core.Windows.Forms.EditableControl"
                .Equals(sender.GetType().ToString())
                &&
                // control is defined as movable
                EditableControls.Contains(sender)
               )
            {
                Point pt;

                pt = Cursor.Position;
                x_offset_on_client_control = evnt_args_mouse.X;
                y_offset_on_client_control = evnt_args_mouse.Y;

                x = x_offset_on_client_control + ((Control)sender).Location.X;
                y = y_offset_on_client_control + ((Control)sender).Location.Y;
                pt = new Point(x, y);

                _point_begin = pt;
            }

            foreach (Control ctrl in Controls)
            {
                if (ctrl.Bounds.Contains(_point_begin))
                {
                    _control_moving = ctrl;
                }
            }
            return;
        }

        /// <summary>
        /// MouseMoveEventHandler moves child control on the screen
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="evnt_args_mouse">
        /// </param>
        protected
           virtual
           void
           MouseMoveEventHandler
           (
             object sender
           , MouseEventArgs evnt_args_mouse
           )
        {
            if (
                ! "Core.Windows.Forms.EditableControl"
                .Equals(sender.GetType().ToString())
                &&
                _control_moving != null
                &&
                evnt_args_mouse.Button == MouseButtons.Left
               )
            {
                Point pt = Cursor.Position;
                _control_moving.Left =
                                (this.PointToClient(pt)).X
                                - 
                                x_offset_on_client_control
                                ;
                _control_moving.Top =
                                (this.PointToClient(pt)).Y
                                -
                                y_offset_on_client_control
                                ;
            }
        }

        /// <summary>
        /// MouseUpEventHandler detects when and where child control released
        /// and sets the ending point for the move of the child control
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="evnt_args_mouse">
        /// </param>
        protected
            virtual
            void
            MouseUpEventHandler
            (
              object sender
            , MouseEventArgs evnt_args_mouse
            )
        {
            if (
                _control_moving != null
                &&
                evnt_args_mouse.Button == MouseButtons.Left
               )
            {
                int x;
                int y;

                x = ((Control)sender).Location.X;
                y = ((Control)sender).Location.Y;

                Point pt = new Point(x, y);
                _point_end = pt;
                _control_moving.Location = _point_end;
                _control_moving = null;
            }

            return;
        }

Using the code

To make any control (let's say SomeUserControl) runtime editable, inherit from EditableControl.

    /// <summary>
    /// UserControl with runtime editable layout extends EditableControl
    /// </summary>
    public partial class SomeUserControl 
        : Core.Windows.Forms.EditableControl
    {
        public SomeUserControl()
            :base()
        {
            InitializeComponent();

       // define movable controls
            base.EditableControls.Add(this.textBox1);
            base.EditableControls.Add(this.dataGridView1);
            base.EditableControls.Add(this.checkBox1);
            base.EditableControls.Add(this.checkedListBox1);
            base.EditableControls.Add(this.button1);

            // prepare EditableControl
            base.initialize();

        }
    }

TODOs

  • Resizable runtime controls
  • Keys to control selection of moving control (Alt, Ctrl)

History

  • First version by moljac++ - 2004.12.03.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

No Biography provided

Comments and Discussions

 
GeneralError and solution Pinmemberequisoide25-Jul-07 16:19 
QuestionCan you favour me a little PinmemberNhilesh B5-Jan-06 2:22 
GeneralTailor Your Application by Building a Custom Forms Designer with .NET (MSDN Article) PinmemberMarc Sommer6-Dec-04 0:52 
Tailor Your Application by Building a Custom Forms Designer with .NET
http://msdn.microsoft.com/msdnmag/issues/04/12/CustomFormsDesigner/default.aspx[^]
 
This article discusses:
Design-time environment fundamentals
Forms designer architecture
The implementation of the forms designer in Visual Studio .NET
Services you need to implement to write a forms designer for your own application
 
Code download available at:
http://download.microsoft.com/download/d/3/1/d31fff33-fd97-488f-9bbd-4b7402905716/CustomFormsDesigner.exe[^]
 

 

And a commercial componment in beta stage at the moment.
seems to be the only runtime form designer component available as for the moment.
Unfortunately commercial.
 
Form Designer .NET
Runtime Form Designer Control
for C#, VB.NET and Delphi 8
version 1.0 beta 2, November 29, 2004
 
Form Designer .NET allows you move and resize any control on your .NET application form at runtime. You need not prepare your form to use Form Designer .NET. Just drop Form Designer .NET control onto any form, assign the DesignedForm property, set Active property to true and enjoy!
 
http://www.greatis.com/dotnet/formdes/[^]
 
Demo (Beta2):
http://www.greatis.com/fdnetdemo.zip[^]

GeneralOther solution PinmemberRobert Rohde5-Dec-04 20:15 
GeneralRe: Other solution PinmemberTNTVN16-Feb-05 23:02 

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
Web04 | 2.8.141220.1 | Last Updated 6 Dec 2004
Article Copyright 2004 by Miljenko Cvjetko
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid