Dynamically added labels disappear in runtime - c#

I add labels to my form programmatically, but they disappear, except last one. I'm sure that given location to them is appropriate. But when the second label appears, first disappears, or when third label appears, second disappears.
Here is my code:
Label[] lenlab = new Label[255];
Label lab = new Label();
lab.Font = new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
lab.ForeColor = Color.White;
lab.BackColor = Color.Transparent;
lab.AutoSize = true;
lenlab[1] = lab;
lenlab[1].Location = new Point(50, panel1.Location.Y + panel1.Height + 20);
lenlab[1].Text = c[1];
this.Controls.Add(lenlab[1]);
for (int i = 2; i < c.Count; i++)
{
lenlab[i] = lab;
lenlab[i].Location = new Point(lenlab[i - 1].Location.X + lenlab[i -1].Width + 40, lenlab[i - 1].Location.Y);
lenlab[i].Text = " + " + c[i];
this.Controls.Add(lenlab[i]);
}

This line is causing every position in your array to have a reference to the same Label you created originally, outside the loop, which means all you're doing is changing the position and text of the same Label inside your loop.
lenlab[i] = lab;
The behavior you're seeing is due to the fact that you can only add a particular control to this.Controls once, so the effect is that you see the same label changing position.
Here's the portion of the Add() method that checks whether the control you're adding already has a parent, and if it does, then it removes it from it's current parent before adding it to the new one. So every time you call this.Controls.Add() with the same Label, it removes it from the Form and then adds it again.
// Remove the new control from its old parent (if any)
if (value.parent != null) {
value.parent.Controls.Remove(value);
}
Instead, create a new Label inside your for loop:
lenlab[i] = new Label();
There are controls that can help you layout controls without the need to calculate a new position each time. In particular, read up on the FlowLayoutPanel and TableLayoutPanel classes.

What you are doing there is basically create one Label, change it several times, and attach it several times to the page. What you end up having on the page is the last version of the Label being added once, which is the expected behavior.
If you want to add several labels, you need to new each of them.

Related

Will Radiobutton created dynamically have fixed text size in Windows Form c#?

I have tried to create a radiobutton dynamically and add it to groupbox/form, but the whole text associated with the radiobutton is not getting displayed. When the radiobutton is added from the designer, the whole text is getting displayed. For dynamically adding radio button am I missing anything or are there any ways to do it?
Please find the sample code below:
public partial class Form1 : Form
{
private void SelectMicrophone_Load(object sender, EventArgs e)
{
System.Windows.Forms.RadioButton r1 = new System.Windows.Forms.RadioButton(); //created a radiobutton
r1.Name = "Microphone(RealTex";
r1.Text = "Microphone(RealTex";
r1.Location = new System.Drawing.Point(15, 15);
this.groupBox1.Controls.Add(r1);
When you set the text property in the designer, it adjust the radio button to the new size to cover the width of the text. By default I think the width is 90 and with the text above it is resized to a width of 124. So when you create the object at runtime, it is probably just keeping the width to 90. You can however just set r1.Width = 124 before adding it to your controls collection.
Keep in mind that you may not know the length each time so you could either set the width to the maximum size that you need or use the TextRender's .MeasureText method to get the size of the text and then just add 20 to that to cover the graphic of the radio button circle that also appears and set the result of the X property to your width before adding the radiobutton to the collection.
RadioButton r1 = new RadioButton();
r1.Text = "This is short text";
//Measure the Text property and get the width and add 20 to accomodate the circle
r1.Width = (TextRenderer.MeasureText(r1.Text, r1.Font)).Width + 20;
r1.Location = new Point(15, 15);
this.Controls.Add(r1);
//Just another RB with even longer text.
r1 = new RadioButton();
r1.Text = "This is even longer text that we want to show";
r1.Width = (TextRenderer.MeasureText(r1.Text, r1.Font)).Width + 20;
r1.Location = new Point(15, 35);
this.Controls.Add(r1);

Drawing a label array in c#

For my project I would need to create clickable tiles sort of like a grid. To do so I have decided to try using an array of labels and clicking on any one of them would cause a mouse click event corresponding to the label clicked. I don't want to use the Visual Studio drag and drop labels to draw the 220 I need so i decided to create an array of Labels. Here is the code I am using to test out the use of the array of labels:
Label[] Tiles = new Label[10];
for (int i = 0; i != 10; i++)
{
for (int n = 0; n != 22; n++)
{
Tiles[i] = new Label();
Tiles[i].Size = new Size(62, 62);
Tiles[i].Location = new System.Drawing.Point(n * 62 + 118, 106 + i * 62);
Tiles[i].Text = (i+n).ToString();
Tiles[i].Name = (i + n).ToString();
Tiles[i].AutoSize = true;
Tiles[i].Click += new System.EventHandler(this.label1_Click);
}
}
I am using this code In the Form1_Load method but the problem is that it doesn't throw an error but also does not actually get the labels on the Form, it just initializes the labels but does not draw them, does someone know how to actually add them to the Form.
This is really easy to do!
In your innermost for loop, add this line:
this.Controls.Add(Tiles[i]);
It first gets all the controls on the form, then add the label in it!
However, I would advise you to add the labels to a Panel, just because since you're creating a grid, you should probably group the labels together using a Panel.
Create a panel in the designer, call it labelPanel or whatever, and call this method instead in the innermost for loop:
this.labelPanel.Controls.Add(Tiles[i]);
Please note that since the position of the labels are now relative to the panel, you need to adjust them again.
You have to add that labels to the form. like, put one groupbox in your form and named it as group1.
now add Labels to that group.
group1.Controls.Add(Tiles[i]);

Create spacing between checkboxes

I'm auto generating checkboxes and putting them into a panel,but when I do that, they all appear at the same point. I can manually move them apart, but this could cause problems down the line. Is there a way to get them to automatically align under each other.
Here's my code:
foreach (Category i in DesktopApp.getBaseCat())
{
checkBox = new CatBox();
checkBox.setCat(i);
checkBox.Text = i.ToString(); // puts the name of the category in the text field
checkBox.Click += new EventHandler(simpleCatBox_Click);
this.categoryPanel.Controls.Add(checkBox); // adds it to the panel
step++; // increments step
}
Give the checkbox a margin (10px in this example)
checkBox.Margin = new Thinkness(10);
Or, if you want different margins
checkBox.Margin = new Thickness(left,top,right,bottom);

Can StatusStrip automatically change its height depending on its items' size?

I've got a statusstrip with a number of items. One of them is a ToolStripStatusLabel with Spring = True.
When the text of the label is too long, one can't see it.
Is it possible to make the statusstrip become higher and show whole text in multiline?
This is an interesting problem....I tried a couple of things but no success...basicall the ToolStripStatusLabel is very limited in capability.
I ended up trying a hack that gives the result you want but am not sure even I would recommend this unless of course this is absolutely necessary...
Here's what I have got...
In the properties of your StatusStrip set AutoSize = false, this is to allow the StatusStrip to be resized to accommodate multiple lines. I am assuming statusStrip called ststusStrip1 containing label called toolStripStatusLabel1.
At form Level declare a variable of TextBox type:
TextBox txtDummy = new TextBox();
At Form Load set some of its properties:
txtDummy.Multiline = true;
txtDummy.WordWrap = true;
txtDummy.Font = toolStripStatusLabel1.Font;//Same font as Label
Handle the paint event of the toolStripStatusLabel1
private void toolStripStatusLabel1_Paint(object sender, PaintEventArgs e)
{
String textToPaint = toolStripStatusLabel1.Tag.ToString(); //We take the string to print from Tag
SizeF stringSize = e.Graphics.MeasureString(textToPaint, toolStripStatusLabel1.Font);
if (stringSize.Width > toolStripStatusLabel1.Width)//If the size is large we need to find out how many lines it will take
{
//We use a textBox to find out the number of lines this text should be broken into
txtDummy.Width = toolStripStatusLabel1.Width - 10;
txtDummy.Text = textToPaint;
int linesRequired = txtDummy.GetLineFromCharIndex(textToPaint.Length - 1) + 1;
statusStrip1.Height =((int)stringSize.Height * linesRequired) + 5;
toolStripStatusLabel1.Text = "";
e.Graphics.DrawString(textToPaint, toolStripStatusLabel1.Font, new SolidBrush( toolStripStatusLabel1.ForeColor), new RectangleF( new PointF(0, 0), new SizeF(toolStripStatusLabel1.Width, toolStripStatusLabel1.Height)));
}
else
{
toolStripStatusLabel1.Text = textToPaint;
}
}
IMP: Do not assign the text property of your label instead put it in Tag we would use it from Tag
toolStripStatusLabel1.Tag = "My very long String";

C# Label not visible in GroupBox

I have a loop that is supposed to go through DataTable and for each row create a new GroupBox, set it's text to value from one column, in that GroupBox I want to put a Label with Text similar to another column in the table.
This is just part of the code!
for (int i = 0; i < tab.Rows.Count; i++)
{
lblbox[i] = new GroupBox();
lblbox[i].Text = tab.Rows[i]["text"].ToString();
lblbox[i].Name = "box no " + i.ToString();
lblbox[i].Visible = true;
this.Controls.Add(lblbox[i]);
lblbox[i].Location = new Point(5, 55 * i);
lblbox[i].Height = 50;
lblbox[i].SendToBack();
importancelbl[i] = new Label();
importancelbl[i].Text = "Importance: " + tab.Rows[i]["importance"].ToString();
importancelbl[i].Name = "implbl" + i.ToString();
importancelbl[i].Visible = true;
lblbox[i].Controls.Add(importancelbl[i]);
importancelbl[i].BringToFront();
Point locP = new Point();
locP.X = lblbox[i].Location.X + 5;
locP.Y = lblbox[i].Location.Y + 15;
importancelbl[i].Location = locP;
}
When i run the code it creates three (I have three rows in my table) GroupBoxes correctly and creates all the labels, but only first label is visible in its Groupbox. When I add those labels to the Form and not to the GroupBox, all of them are visible, but I want them to be in boxes...
I've tried pretty much everything and I'm still very confused (espacially by the behavior of the first label). I know the mistake is probably obvious and stupid, but I just can't find it!
Control.Location is relative to its parent, so set Location for the label to (5, 15).
locP.X = 5;
locP.Y = 15;
My guess is that they are somehow overlapping and making each other disappear somehow.
Could you try posting pictures of the form when it works and when it doesn't? Also add all your code?
Try to preform adding
lblbox[i].Controls.Add(importancelbl[i]);
this.Controls.Add(lblbox[i]);
after setting all your properties

Categories