A simple example of adding movable label controls at runtime






4.44/5 (4 votes)
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;
}
}
}