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

A simple example of adding movable label controls at runtime

, 23 Jan 2013
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.

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

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

Comments and Discussions

 
SuggestionSuggestion PinmemberInTRUEdeR23-Jan-13 10:59 
GeneralRe: Suggestion PinmemberTarek Elqusi24-Jan-13 4:06 
SuggestionExplanations PinmvpMika Wendelius28-Dec-12 9:38 
GeneralRe: Explanations PinmemberTarek Elqusi5-Jan-13 0:44 
GeneralRe: Explanations PinmvpMika Wendelius6-Jan-13 5:02 
QuestionMy vote of 3 PinmvpDave Kreskowiak27-Dec-12 11:53 
The movable label functionality should be in it's own control, not on the form. This makes the functionality reusable in other forms and applications without having to copy and paste code.
 
It would also greatly simplify the code behind the form.

AnswerRe: My vote of 3 PinmemberTarek Elqusi5-Jan-13 0:54 
GeneralRe: My vote of 3 PinmvpDave Kreskowiak5-Jan-13 7:12 
GeneralMy vote of 5 Pinmembermember6027-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 | Mobile
Web01 | 2.8.140926.1 | Last Updated 23 Jan 2013
Article Copyright 2012 by Tarek Elqusi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid