Click here to Skip to main content
11,806,026 members (59,175 online)
Click here to Skip to main content

A simple example of adding movable label controls at runtime

, 23 Jan 2013 CPOL 15.8K 1.1K 14
Rate this:
Please Sign up or sign in to vote.
I created a simple form with a button to add a label control at run time sequentially numbered; labels are movable and lines are drawn between labels.


This is my first article, I intended it for beginners like me in C# as an example.

The code attached is an example of assigning events at run time and using delegates. It is simple and sheds light on the ideas used in graphics programs used by engineers. This code could be enhanced by adding rotation functionality around three dimensional axes.


The image below shows the screen with some labels added and moved from their initial places by mouse and lines are drawn between them.

Using the code

In this sample I created a simple form with a button to add a label control at run time sequentially numbered. When adding each label I assign to it labelMouseDown and labelMouseMove events. I use these two methods to draw lines connecting the added labels. The lines drawn have two modes, either only one line is drawn from the last added label to the previous one, or the "LinkToAll" mode, where a line is drawn to each existing label.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace MovableLabels
    public partial class Form1 : Form
        Label[] lblArray;  // an array to hold all added controls 
        Point move;        
        // drawing variables
        Graphics g;
        Pen green = new Pen(Color.Green, 2);
        // position
        int lblNum = 0;
        const int Horizontal = 50;
        int Vertical = 0;
        // delegate
        delegate void callDrawDel();
        callDrawDel callDraw;
        public Form1()
            g = this.CreateGraphics();
            callDraw = drawLines;
        private void button1_Click(object sender, EventArgs e)
            // Create the label and define its initial locatio
            Label o = new Label();
            o.Visible = true;
            o.Top = Vertical*lblNum ;
            Vertical += 10;
            o.Left = Horizontal * lblNum;
            o.Text = (++lblNum).ToString();
            o.AutoSize = true;         
            // assign moving related methods
            o.MouseDown += new MouseEventHandler(this.labelMouseDown);
            o.MouseMove += new MouseEventHandler(this.labelMouseMove);
            // add to the screen
            List<Label> lblList = new List<Label>();
            foreach (Control c in Controls)
                if (c is Label)
            lblArray = lblList.ToArray();  
            // draw lines
            callDraw();    // using delegate
        private void labelMouseDown(object sender, MouseEventArgs e)
            move = e.Location;
        // the method do the actual label moving
        private void labelMouseMove(object sender, MouseEventArgs e)
            // cast the sender object to a control to access the Left and Top properties
            Control o = (Control)sender;
            if (e.Button == MouseButtons.Left)
                o.Left += e.X - move.X;
                o.Top += e.Y - move.Y;
        // The methods drawLines and drawLinesAll are just examples of drawing lines in varied forms
        // An enormous number of methods could be invented to connect lines resulting in very glorious 
        // shapes
        // The check box could be changed to a list box to show methods as you wish
        private void drawLines()
            for (int i = 1; i < lblArray.Length; i++)
                lineDraw(lblArray[i - 1], lblArray[i]);
        private void drawLinesAll()
            for (int k = 0; k < lblArray.Length; k++)
                Label L1 = lblArray[k];
                for (int j = k + 1; j < lblArray.Length; j++)                    
                    lineDraw(L1, lblArray[j]);
        private void lineDraw(Label L1, Label L2)
            // define the starting & ending point 
            int x1, x2, y1, y2;
            // starting point from the center of the first label L1
            x1 = L1.Location.X + L1.Width / 2;
            y1 = L1.Location.Y + L1.Height / 2;
            // starting point from the center of the second label L2
            x2 = L2.Location.X + L2.Width / 2;
            y2 = L2.Location.Y + L2.Height / 2;
            g.DrawLine(green, x1, y1, x2, y2);
        private void LinkToAll_CheckedChanged(object sender, EventArgs e)
            // decide what method to call
            bool chk = LinkToAll.CheckState == CheckState.Checked;
            if (chk) 
                 callDraw = drawLinesAll; 
            else callDraw = drawLines;
            // then call it via delegate type
        private void btnClear_Click(object sender, EventArgs e)
            // remove all labels using the array lblArray
            foreach (Control c in lblArray)
            lblNum = Vertical = 0;


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


About the Author

Tarek Elqusi
Software Developer (Senior)
Egypt Egypt
I am an ERP developer using VFP9
I started as a Clipper 5.2 with DBase III+ in 1995, I worked with Access 2.0
Then I converted to VFP5.0 then VFP9, I worked on an ERP application written by FoxPro2.6

Recently, I started learning C#
I have a tendency to do generic work and build generic functions, I try to do that using C#

I'm preparing myself now to be a Framework C# programmer
First step I'll read the C# specification, when done I'll update this, I've already started this in Feb-27-2013

You may also be interested in...

Comments and Discussions

SuggestionSuggestion Pin
InTRUEdeR23-Jan-13 10:59
memberInTRUEdeR23-Jan-13 10:59 
GeneralRe: Suggestion Pin
Tarek Elqusi24-Jan-13 4:06
memberTarek Elqusi24-Jan-13 4:06 
SuggestionExplanations Pin
Mika Wendelius28-Dec-12 9:38
mvpMika Wendelius28-Dec-12 9:38 
Since this is an article I would like to see more explanations about the code. The idea of an article is to teach others to do the same thing, not just to show how to use a ready made code.
GeneralRe: Explanations Pin
Tarek Elqusi5-Jan-13 0:44
memberTarek Elqusi5-Jan-13 0:44 
GeneralRe: Explanations Pin
Mika Wendelius6-Jan-13 5:02
mvpMika Wendelius6-Jan-13 5:02 
QuestionMy vote of 3 Pin
Dave Kreskowiak27-Dec-12 11:53
mvpDave Kreskowiak27-Dec-12 11:53 
AnswerRe: My vote of 3 Pin
Tarek Elqusi5-Jan-13 0:54
memberTarek Elqusi5-Jan-13 0:54 
GeneralRe: My vote of 3 Pin
Dave Kreskowiak5-Jan-13 7:12
mvpDave Kreskowiak5-Jan-13 7:12 
GeneralMy vote of 5 Pin
member6027-Apr-12 22:15
membermember6027-Apr-12 22:15 

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
Web01 | 2.8.151002.1 | Last Updated 23 Jan 2013
Article Copyright 2012 by Tarek Elqusi
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid