Dynamically creating labels and textboxes in a panel

W

Wade

Hi all,

I have an array of polygons, and I need to create controls so that people
can set absolute coordinates (in decimal degrees) for each of the points
within each of the polygons (we also call these polygons sections).

To do this, I have created a method that I call and pass some information to
it so that it can create the appropriate labels and textboxes. While this
has worked successfully, I have found that it can be very slow if I'm
creating, say, two sections each with 10+ points.

Can anyone give me any advice as to a better way to do this? Thanks in
advance!

Here's the method I'm using for creating the controls:

private void CreateCoordinateControls()
{
Point pt = new Point(0, 0);
Label lbl = null;
TextBox txt = null;
Point ptLabel = new Point();
Point ptTextbox = new Point();

int iSectionNum = 1;
int iPointNum;

// loop through each polygon
foreach (DictionaryEntry m_DE in polygons)
{
polygonPointsArray = (ArrayList)m_DE.Value;
polygonPoints = new Point[polygonPointsArray.Count];

iSectionNum += 1;
iPointNum = 1;

// loop through each point
for (int i = 0; i < polygonPointsArray.Count; i++)
{
polygonPoints = (Point)polygonPointsArray;

// create the controls for this point
DefinePointControls(
pt,
"Point",
iPointNum,
iSectionNum,
lbl,
txt,
ptLabel,
ptTextbox);

// increment
iPointNum += 1;
pt.Y += 22;
}
}
}

private void DefinePointControls(
Point pt, // starting point of the controls
string sLabelText, // text to use for the label
int iControlNum, // the current row number
int iSectionNum, // the current section number
Label lbl, // the label control
TextBox txt, // the textbox control
Point ptLabel, // variable used for determining label location
Point ptTextbox // variable used for determining textbox
location
)
{
// set the local variables

ptLabel = pt;
ptTextbox = pt;

// update the label to vertically align it with the middle of
the textbox
ptLabel.Y += 3;

// Create the point label
lbl = new Label();

ptLabel.X += 17;

lbl.Location = ptLabel;
lbl.Name = "lblPoint" + iSectionNum.ToString() + "_" +
iControlNum.ToString();
lbl.Size = new System.Drawing.Size(33, 20);
lbl.Text = sLabelText;

pnlCoordinates.Controls.Add(lbl);

// X-coordinate textbox
txt = new TextBox();

ptTextbox.X += 50;

txt.Location = ptTextbox;
txt.Name = "txtPointX" + iSectionNum.ToString() + "_" +
iControlNum.ToString();
txt.Size = new System.Drawing.Size(74, 20);
txt.Text = "";

pnlCoordinates.Controls.Add(txt);

// X-coordinate label
lbl = new Label();

ptLabel.X += (33 + 74);

lbl.Location = ptLabel;
lbl.TextAlign = ContentAlignment.TopCenter;
lbl.Name = "lblX" + iSectionNum.ToString() + "_" +
iControlNum.ToString();
lbl.Size = new System.Drawing.Size(10, 20);
lbl.Text = "X";

pnlCoordinates.Controls.Add(lbl);

// Y-Coordinate textbox
txt = new TextBox();

ptTextbox.X += 84;

txt.Location = ptTextbox;
txt.Name = "txtPointY" + iSectionNum.ToString() + "_" +
iControlNum.ToString();
txt.Size = new System.Drawing.Size(74, 20);
txt.Text = "";

pnlCoordinates.Controls.Add(txt);

// Y-coordinate label
lbl = new Label();

ptLabel.X += 84;

lbl.Location = ptLabel;
lbl.TextAlign = ContentAlignment.TopCenter;
lbl.Name = "lblY" + iSectionNum.ToString() + "_" +
iControlNum.ToString();
lbl.Size = new System.Drawing.Size(10, 20);
lbl.Text = "Y";

pnlCoordinates.Controls.Add(lbl);
}
 
T

tamberg

An article (can't remember the title) suggested to replace

a.Controls.Add(b); by b.Parent = a;

which is told to be more efficient. Further it might be possible to
reuse a number of pre-created controls rather than instanciating new
ones.
 
W

Wade

Thanks, Tamberg.

Sorry for the silly question, but how would I reuse the same control for
multiple instances? Don't I need to re-instantiate it each time?
 
T

tamberg

Assuming your UI displays more than one set of data (not simultaneous)
you could reuse multiple instances (from sort of a control-pool) to
display different sets of data.
 
B

Brian Nantz

So instead of doing this:

for(int i =0; i<10; i++)
{
Controls.Add(new Label);
}

You can save performance by doing this:

Label l = new Label();
for(int i =0; i<10; i++)
{
Controls.Add(l);
}

You just have to remember to change the positioning.
 
T

tamberg

Adding the same instance more than once won't work. But if you display
multiple sets of data (one set after the other, refreshing the screen
for a new set) you could reuse a fixed number of instances.
 
W

Wade

Seems to me that this would just keep moving the same label around the
screen, until it finally finished and I had only one label in the final
position. Right?
 
W

Wade

Hi Tam,

Unfortunately, I don't follow. What do you mean, "refreshing the screen for
a new set"? I would really appreciate a simple example.

I need to be able to create X number of textboxes so that the user can
associate some data to pre-existing points defined in a polygon. If you
have a method that would make the rendering of these controls faster than
what I originally posted, I would be very grateful.

Thanks,

Wade
 
L

Lars Black

An article (can't remember the title) suggested to replace
a.Controls.Add(b); by b.Parent = a;

Using two calls to set size and location also slows down..
I've created a Label subclass like this:

public class MyLabel : System.Windows.Forms.Label
{
public Label(System.Windows.Forms.Control aParent, int x, int y, int w,
int h) : this ()
{
this.Parent = aParent;
this.Bounds = new Rectangle(x, y, w, h);
}
}

So in you code, just use
lbl = new MyLabel(pnlCoordinates, ptLabel.X, ptLabel.Y, 10, 20)
or something simular..

I gave my application a visible speed boost to create all controls this way.
Your code will also look more clean :)

Cheers,
Lars
 
L

Lars Black

What's the best way to dispose of dynamic controls such as these?

lbl.Dispose();

Cheers,
Lars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top