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

A simple example of adding movable label controls at runtime

By , 23 Jan 2013
 

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)

About the Author

Tarek Elqusi
Software Developer (Senior)
Egypt Egypt
Member
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

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
SuggestionSuggestionmemberInTRUEdeR23 Jan '13 - 10:59 
Try this: Draggable WinForms Controls[^] to make your life easier Smile | :)
GeneralRe: SuggestionmemberTarek Elqusi24 Jan '13 - 4:06 
Thanks, I checked your code and it is nice, I voted 5 for you. Moreover, I got from it the idea of extension methods
SuggestionExplanationsmvpMika 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: ExplanationsmemberTarek Elqusi5 Jan '13 - 0:44 
Hi Mika
Thanks for your comment. I agree with you, but when I first posted this article I had little experience in using the CodeProject editor, and finally I posted it as it is no. I'll make it more explained in the next revision.
GeneralRe: ExplanationsmvpMika Wendelius6 Jan '13 - 5:02 
Looking forward to it Thumbs Up | :thumbsup:
The need to optimize rises from a bad design.My articles[^]

QuestionMy vote of 3mvpDave 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 3memberTarek Elqusi5 Jan '13 - 0:54 
Hi Dave
This is a good idea, I think I can employ it by detecting the parent of the added label , let it p,whatever it is a form or any other container type, then creating the graphics object using p.CreateGraphics()
GeneralRe: My vote of 3mvpDave Kreskowiak5 Jan '13 - 7:12 
Create what Graphics object? What are you drawing??
 
You don't need a Graphics object at all. All you're doing is manipulating the Location coords on the label.
 
I know this because I've already done it: Create your Own Runtime Movable Windows Forms Controls[^].

GeneralMy vote of 5membermember6027 Apr '12 - 22:15 
My 5!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 23 Jan 2013
Article Copyright 2012 by Tarek Elqusi
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid