Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A simple example of adding movable label controls at runtime

0.00/5 (No votes)
23 Jan 2013 1  
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.

Introduction

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.

Detail

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()
        {
            InitializeComponent();
            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
            this.Controls.Add(o);
            List<Label> lblList = new List<Label>();
            foreach (Control c in Controls)
                if (c is Label)
                    lblList.Add((Label)c);
            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;
                callDraw();
            }
        }
        // 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()
        {
            g.Clear(this.BackColor);
            for (int i = 1; i < lblArray.Length; i++)
                lineDraw(lblArray[i - 1], lblArray[i]);
        }
        private void drawLinesAll()
        {
            g.Clear(this.BackColor);
            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
            callDraw();
        }
        private void btnClear_Click(object sender, EventArgs e)
        {
            // remove all labels using the array lblArray
            foreach (Control c in lblArray)
              this.Controls.Remove(c);
            g.Clear(this.BackColor);
            lblNum = Vertical = 0;
        }
    }
}

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