Dynamically added labels only show one - c#

Ok so I decided to add controls to a panel on form_load based on labels in an array. Below is my code, but no matter how many files I upload through the button listener and reload this form, it only displays one label and nothing more. Why is it only displaying one? I have added a breakpoint and verified that the count does go up to 2, 3, etc.
Code:
public partial class Attachments : Form
{
ArrayList attachmentFiles;
ArrayList attachmentNames;
public Attachments(ArrayList attachments, ArrayList attachmentFileNames)
{
InitializeComponent();
attachmentFiles = attachments;
attachmentNames = attachmentFileNames;
}
private void Attachments_Load(object sender, EventArgs e)
{
ScrollBar vScrollBar1 = new VScrollBar();
vScrollBar1.Dock = DockStyle.Right;
vScrollBar1.Scroll += (sender2, e2) => { pnl_Attachments.VerticalScroll.Value = vScrollBar1.Value; };
pnl_Attachments.Controls.Add(vScrollBar1);
Label fileName;
for (int i = 0; i < attachmentNames.Count; i++)
{
fileName = new Label();
fileName.Text = attachmentNames[i].ToString();
pnl_Attachments.Controls.Add(fileName);
}
}
private void btn_AddAttachment_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string fileName = openFileDialog1.FileName;
attachmentFiles.Add(fileName);
attachmentNames.Add(Path.GetFileName(fileName));
this.Close();
}
}
}

This is because the labels are all stacking on top of each other. You will need to specify a top for each one or use an auto-flow panel.
Adding the following line after creating the new label will ensure all labels are visible (you may have to adjust the multiplier depending on your font):
fileName.Top = (i + 1) * 22;

As competent_tech stated the labels are stacking on top of each other, but another approach is to modify the location value of the label.The benefit to this is you can control the absolute location of the label.
fileName.Location = new Point(x, y);
y += marginAmount;
x is the vertical position on the form and y is the horizontal location on the form. Then all that has to be modified is the amount of space you want in between each label in the marginAmount variable.
So in this for loop
for (int i = 0; i < attachmentNames.Count; i++)
{
fileName = new Label();
fileName.Text = attachmentNames[i].ToString();
pnl_Attachments.Controls.Add(fileName);
}
You could modify it to this:
for (int i = 0; i < attachmentNames.Count; i++)
{
fileName = new Label();
fileName.Text = attachmentNames[i].ToString();
fileName.Location = new Point(x, y);
y += marginAmount;
pnl_Attachments.Controls.Add(fileName);
}
Then all you have to do is define x, y, and the marginAmount.

Related

Guna framework VScrollBar in C#

I'm trying to design a VScrollBar in C# using Guna framework. The panel has 10 Labels on it. I used this code but It doesn't work for me
vScrollHelper = new Guna.UI.Lib.ScrollBar.PanelScrollHelper(panel2, gunaVScrollBar1, true);
Random r = new Random();
for (int i = 0; i <= 40; i++)
{
Label lbl = new Label();
lbl.AutoSize = true;
lbl.Text = "Label " + i.ToString() + " ================================================================";
lbl.Location = new Point(6, i * lbl.Height);
panel2.Controls.Add(lbl);
}
vScrollHelper.UpdateScrollBar();
}
private void Panel1_Resize(object sender, EventArgs e)
{
if (vScrollHelper != null) vScrollHelper.UpdateScrollBar();
}
If you want 10 labels, consider a loop with 10 iterations:
for (int i = 0; i < 10; i++)
{
// Code to add labels here...
}
The scroll does not have to be inside the parent of the object, you have to put it outside the panel, but without moving position, you can use CTRL+ALT+R, and take it out of the parent object

How to access and change the property of a label that I created dynamically

I wanna change the Text properties of Label using Buttons just like in hangman; but after I created the Label, I became confused when I try to access the specific Label
// creating label
for (int i = 0; i < numericUpDown1.Value; i++)
{
Label l = new Label();
l.Text = "_";
l.Width = 20;
l.Height = 25;
l.Left = i * 20 + 510;
l.Top = 20;
l.BackColor = Color.Transparent;
groupBox2.Controls.Add(l);
}
// function to change the label text
// if I clicked the button
// the first label text will be changed to the text in the button i clicked
private void B_Click(object sender, EventArgs e)
{
var thsBtn = (Button)sender;
bool benar = false;
if (benar == false)
{
thsBtn.Text = " ";
thsBtn.Enabled = false;
}
else
{
thsBtn.Enabled = false;
}
}
You can organize created Labels into a collection, say, List<Label>:
private List<Label> m_CreatedLabels = new List<Label>();
...
// Remove all previous labels
foreach (Label lbl in m_CreatedLabels)
lbl.Dispose();
m_CreatedLabels.Clear();
// Create new ones
for (int i = 0; i < numericUpDown1.Value; i++) {
m_CreatedLabels.Add(new Label() {
Text = "_",
Width = 20,
Height = 25,
Left = i * 20 + 510,
Top = 20,
BackColor = Color.Transparent,
Parent = groupBox2
});
}
Now you have m_CreatedLabels collection to work with created Labels, e.g.
private void B_Click(object sender, EventArgs e) {
var thsBtn = sender as Button;
// you may want to add a condition into FirstOrDefault(), e.g.
// .FirstOrDefault(lbl => lbl.Text == "_")
// - first label with "_" Text
Label lblToProcess = m_CreatedLabels
.FirstOrDefault();
if (null != lblToProcess)
lblToProcess.Text = thsBtn.Text;
thsBtn.Enabled = false;
}
One option here is to give your dynamically created Label instances a Name. From there, you should be able to use ControlCollection.Find to find your Label instances by name.
private void CreateLabels()
{
for (int i = 0; i < numericUpDown1.Value; i++)
{
Label l = new Label();
l.Name = $"DynamicLabel{i}";
l.Text = "_";
l.Width = 20;
l.Height = 25;
l.Left = i * 20 + 510;
l.Top = 20;
l.BackColor = Color.Transparent;
groupBox2.Controls.Add(l);
}
}
private void DoSomethingWithADynamicLabel(int dynamicLabelIndex)
{
Label l = groupBox2.Controls.Find($"DynamicLabel{i}", true).FirstOrDefault() as Label;
if (l is null)
{
// Couldn't find the label...
return;
}
// Do something with l
}
When creating the Label instances inside CreateLabels, I'm simply appending the for loop's counter to the string "DynamicLabel". This gives you a bunch of Labels with names like "DynamicLabel0", "DynamicLable1", "DynamicLabel2", etc...
Then in DoSomethingWithADynamicLabel, assuming you have the index of the Label you want to deal with, you can use groupBox2.Controls.Find to actually find the Label you're interested in. ControlCollection.Find returns Control[], so calling FirstOrDefault will take the first item from the array or null if no Control with the given name exists.

How to create many labels and textboxes dynamically depending on the value of an integer variable?

Is there any way to dynamically create and display 'n' Labels with 'n' corresponding Textboxs when we know value of 'n' after for example, clicking "Display" button.
Let me know if anything make you don't understand my question. Thank you!
I am working with VS C# Express 2010 Windows Form.
I would create a user control which holds a Label and a Text Box in it and simply create instances of that user control 'n' times. If you want to know a better way to do it and use properties to get access to the values of Label and Text Box from the user control, please let me know.
Simple way to do it would be:
int n = 4; // Or whatever value - n has to be global so that the event handler can access it
private void btnDisplay_Click(object sender, EventArgs e)
{
TextBox[] textBoxes = new TextBox[n];
Label[] labels = new Label[n];
for (int i = 0; i < n; i++)
{
textBoxes[i] = new TextBox();
// Here you can modify the value of the textbox which is at textBoxes[i]
labels[i] = new Label();
// Here you can modify the value of the label which is at labels[i]
}
// This adds the controls to the form (you will need to specify thier co-ordinates etc. first)
for (int i = 0; i < n; i++)
{
this.Controls.Add(textBoxes[i]);
this.Controls.Add(labels[i]);
}
}
The code above assumes that you have a button btnDisplay and it has a onClick event assigned to btnDisplay_Click event handler. You also need to know the value of n and need a way of figuring out where to place all controls. Controls should have a width and height specified as well.
To do it using a User Control simply do this.
Okay, first of all go and create a new user control and put a text box and label in it.
Lets say they are called txtSomeTextBox and lblSomeLabel. In the code behind add this code:
public string GetTextBoxValue()
{
return this.txtSomeTextBox.Text;
}
public string GetLabelValue()
{
return this.lblSomeLabel.Text;
}
public void SetTextBoxValue(string newText)
{
this.txtSomeTextBox.Text = newText;
}
public void SetLabelValue(string newText)
{
this.lblSomeLabel.Text = newText;
}
Now the code to generate the user control will look like this (MyUserControl is the name you have give to your user control):
private void btnDisplay_Click(object sender, EventArgs e)
{
MyUserControl[] controls = new MyUserControl[n];
for (int i = 0; i < n; i++)
{
controls[i] = new MyUserControl();
controls[i].setTextBoxValue("some value to display in text");
controls[i].setLabelValue("some value to display in label");
// Now if you write controls[i].getTextBoxValue() it will return "some value to display in text" and controls[i].getLabelValue() will return "some value to display in label". These value will also be displayed in the user control.
}
// This adds the controls to the form (you will need to specify thier co-ordinates etc. first)
for (int i = 0; i < n; i++)
{
this.Controls.Add(controls[i]);
}
}
Of course you can create more methods in the usercontrol to access properties and set them. Or simply if you have to access a lot, just put in these two variables and you can access the textbox and label directly:
public TextBox myTextBox;
public Label myLabel;
In the constructor of the user control do this:
myTextBox = this.txtSomeTextBox;
myLabel = this.lblSomeLabel;
Then in your program if you want to modify the text value of either just do this.
control[i].myTextBox.Text = "some random text"; // Same applies to myLabel
Hope it helped :)
Here is a simple example that should let you keep going add somethink that would act as a placeholder to your winform can be TableLayoutPanel
and then just add controls to it
for ( int i = 0; i < COUNT; i++ ) {
Label lblTitle = new Label();
lblTitle.Text = i+"Your Text";
youlayOut.Controls.Add( lblTitle, 0, i );
TextBox txtValue = new TextBox();
youlayOut.Controls.Add( txtValue, 2, i );
}
Suppose you have a button that when pressed sets n to 5, you could then generate labels and textboxes on your form like so.
var n = 5;
for (int i = 0; i < n; i++)
{
//Create label
Label label = new Label();
label.Text = String.Format("Label {0}", i);
//Position label on screen
label.Left = 10;
label.Top = (i + 1) * 20;
//Create textbox
TextBox textBox = new TextBox();
//Position textbox on screen
textBox.Left = 120;
textBox.Top = (i + 1) * 20;
//Add controls to form
this.Controls.Add(label);
this.Controls.Add(textBox);
}
This will not only add them to the form but position them decently as well.
You can try this:
int cleft = 1;
intaleft = 1;
private void button2_Click(object sender, EventArgs e)
{
TextBox txt = new TextBox();
this.Controls.Add(txt);
txt.Top = cleft * 40;
txt.Size = new Size(200, 16);
txt.Left = 150;
cleft = cleft + 1;
Label lbl = new Label();
this.Controls.Add(lbl);
lbl.Top = aleft * 40;
lbl.Size = new Size(100, 16);
lbl.ForeColor = Color.Blue;
lbl.Text = "BoxNo/CardNo";
lbl.Left = 70;
aleft = aleft + 1;
return;
}
private void btd_Click(object sender, EventArgs e)
{
//Here you Delete Text Box One By One(int ix for Text Box)
for (int ix = this.Controls.Count - 2; ix >= 0; ix--)
//Here you Delete Lable One By One(int ix for Lable)
for (int x = this.Controls.Count - 2; x >= 0; x--)
{
if (this.Controls[ix] is TextBox)
this.Controls[ix].Dispose();
if (this.Controls[x] is Label)
this.Controls[x].Dispose();
return;
}
}

Newly created label will not show GUI

I am having some issues making my label show up in the gui... any thoughts?
private void addNewExcerciseButton_Click(object sender, EventArgs e)
{
int y = 305;
int x= 61;
string tempExcercise = excerciseTextBox.Text;
excerciseTextBox.Clear();
Label[] excerciseLabels = new Label[numExercises];
for (int i = 0; i < numExercises; ++i)
{
excerciseLabels[i] = new Label();
excerciseLabels[i].Text = ToString("{0}. {1}", i + 1, tempExcercise);;
excerciseLabels[i].Location = new System.Drawing.Point(x, y);
x += 10;
y += 10;
++numExercises;
}
}
thanks in advance.
numExercises is global.
You have to add each new Label to the collection of Controls contained by a visible Control (such as your Form). You're creating and setting them up, but they aren't part of the GUI yet until they're in the control hierarchy.
Add the following line after setting the location of the label:
this.Controls.Add(exerciseLabels[i]);
You need to add the label to the GUI:
this.Controls.Add(excersizeLabels[i]);
As a side note, there is no point in using an array.

c# creating dynamic textbox in a second form

I am trying to write a code in order to create dynamic textboxes.
I have Function class and have a second form in my program named ProductForm.cs
What I wanna do is to read some data with a function named GetSpecs in my Function.cs and than inside GetSpecs I want to call a function in another class and send data to my other function under ProductForm.cs class.
I am getting blank form at the end.
a part of my GetSpecs function:
private String GetSpecs(String webData)
{
......
ProductForm form2 = new ProductForm();
form2.CreateTextBox(n);
}
ProductForm.cs
public void CreateTextBox(int i)
{
ProductForm form2 = new ProductForm();
form2.Visible = true;
form2.Activate();
int x = 10;
int y = 10;
int width = 100;
int height = 20;
for (int n = 0; n < i; n++)
{
for (int row = 0; row < 4; row++)
{
String name = "txtBox_" + row.ToString();
TextBox tb = new TextBox();
tb.Name = name;
tb.Location = new Point(x, y);
tb.Height = height;
tb.Width = width + row * 2;
x += 25 + row * 2;
this.Controls.Add(tb);
}
y += 25;
}
}
I get a blank form of ProductForm. Textboxes are not created or I cannot see them.
If I put textbox inside
private void ProductForm_Load(object sender, EventArgs e)
I can see textboxes.
You're creating showing a brand new ProductForm instance (in the form2 variable), then adding controls to this (which is never shown).
You are adding the controls to the current form: this.Controls.Add(tb);, you need to add them to the other form:
form2.Controls.Add(tb);

Categories