Issue with Creating List of Link Labels - c#

I am using code as below to create a list of link labels :
LinkLabel[] lnkArray = new LinkLabel[10];
for (int i = 0; i < 10; i++)
{
lnkArray[i] = new LinkLabel();
lnkArray[i].Text = "test" + i;
lnkArray[i].Location = new System.Drawing.Point(20 + (i + 5), 50);
lnkArray[i].Size = new Size(200, 25);
}
panel1.Controls.AddRange(lnkArray);
Here is a image of the result :
It looks good to me but this always makes one linklabel in the panel with text = test0 .So basically it is adding just the first one in the list any solution ?

There is no problem with AddRange.
The problem in your code is that the LinkLabel(s) is overlapping.
The width of the LinkLabel in your code is 200. Therefore, you should leave at least 200px gap between the labels.
Try changing your code to this:-
LinkLabel[] lnkArray = new LinkLabel[10];
for (int i = 0; i < 10; i++)
{
lnkArray[i] = new LinkLabel();
lnkArray[i].Text = "test" + i;
lnkArray[i].Location = new System.Drawing.Point(20 + (i + 200), 50);
lnkArray[i].Size = new Size(200, 25);
}
panel1.Controls.AddRange(lnkArray);

simply use this instead of array
for (int i = 0; i < 10; i++)
{
LinkLabel lnkLbl = new LinkLabel();
// add properties i.e Text , Location , size
panel1.Controls.Add(lnlLbl);
}

Related

Creating Labels at run time from a variable

Im trying to create a label in runtime. the number of labels depends on the number of items of another variable and the labels do not show. The code is as follows.
int NoofItems = tillfrm.lvbasket.Items.Count;
for (int i = 0; i < NoofItems + 1; i++)
{
Label lblitems = new Label();
lblitems.Name = "lblItems" + i;
lblitems.Font = new Font ("Calibri",lblitems.Font.Size);
lblitems.Location = new Point(95, (152 + (19 * i)));
lblitems.ForeColor = System.Drawing.Color.Black;
lblitems.Show();
lblitems.AutoSize = true;
lblitems.Text = tillfrm.lvbasket.Items[0].Text;
this.Controls.Add(lblitems);
}
some help would be appreciated thanks.
You should change tillfrm.lvbasket.Items[0].Text to tillfrm.lvbasket.Items[i].Text.
And i < NoofItems + 1 to i < NoofItems, because array size is NoofItems.
Try it like this, create a function, make the array GLOBAL,
protected void myFunction()
{
int NoofItems = tillfrm.lvbasket.Items.Count;
for (int i = 0; i < NoofItems; i++)
{
Label lblitems = new Label();
lblitems.Name = "lblItems" + i;
lblitems.Font = new Font ("Calibri",lblitems.Font.Size);
lblitems.Location = new Point(95, (152 + (19 * i)));
lblitems.ForeColor = System.Drawing.Color.Black;
lblitems.Show();
lblitems.AutoSize = true;
lblitems.Text = tillfrm.lvbasket.Items[i].Text;
this.Controls.Add(lblitems);
}
}
Then call this function in Form_load() function or Page_load() function like this
protected void Form_Load(Object sender , EventArgs e)
{
myFunction();
}

C# Generating Labels Dynamically

I have got the below code to generate labels using for loop, however there is a problem with the for loop, if the productList has 4 items, it generates 1 label instead of 4. I can't figure out what the problem is.
List<models.Car> carList = carController.getCars();
for (int i = 0; i < carList.Count; i++)
{
List<models.Product> productList = productController.getProducts(carList[i].Model);
for (int j = 0; j < productList.Count; j++)
{
productLabels.Add(new Label());
var productLabelsPoint = new System.Drawing.Point(200, 40 + i * 50);
(productLabels[j] as Label).Location = productLabelsPoint;
(productLabels[j] as Label).Size = new System.Drawing.Size(150, 15);
(productLabels[j] as Label).Text = productList[j].Title;
this.Tab.TabPages["tab1"].Controls.Add((productLabels[j] as Label));
}
}
This only relies on i, not on j:
System.Drawing.Point productLabelsPoint = new System.Drawing.Point(200, 40 + i * 50);
So you might be drawing the labels one on top of the other.
In which case, you'd need to add j into the mix, for example like this:
System.Drawing.Point productLabelsPoint = new System.Drawing.Point(200, 40 + i * 50 + j * 50);
I would also change the way you are referencing the label. (I can't tell from the context if what you are doing is okay or not, as it depends how that productLabels variables has been instantiated.)

Split the content of textbox into respective individual textboxes at run time in c#?

I want the text contents of a TextBox to split into respective individual Textbox carrying a single character using c# windows application form.
Eg : A single Textbox containing text as-[Orange]
Expected output:-
in 20 separate textboxes
[o][r][a][n][g][e][][][][][][][][][][][][][][]
Till now I have done this..
`string name = textBox1.Text;
string str = name;
int chunkSize = 1;
Int32 stringLength = str.Length;
for (int i = 0; i < stringLength; i += chunkSize)
{
TextBox txtbox = new TextBox();
//if (i + chunkSize > stringLength)
//chunkSize = stringLength - i;
string singlechar = str.Substring(i, chunkSize);
txtbox.TextAlign = HorizontalAlignment.Center;
txtbox.BorderStyle = BorderStyle.FixedSingle;
txtbox.Font = new Font(txtbox.Font, FontStyle.Bold);
txtbox.Text = singlechar;
//txtbox.MaxLength = 1;
int a = 30;
int x = (i + 10) * a;
txtbox.Text = txtbox.Text.ToUpper();
txtbox.Location = new System.Drawing.Point(x, 100);
txtbox.BackColor = Color.White;
txtbox.Size = new System.Drawing.Size(30, 20);
this.Controls.Add(txtbox);
}`
I think you want this:-
textBox1 = mainTextBox.Text[0] ;
textBox2 = mainTextBox.Text[1] ;
// and so on..
assuming other TextBoxs in Panel named panel1 you can write something like :
for (int i = 0; i < textBox1.Text.Length; i++)
((TextBox)panel1.Controls[i]).Text = textBox1.Text[i].ToString();

How to assign a pre existing panel to an array like panel[0,0]?

Im trying to create a chess strategy application in c#. I have placed the panels in the form designer where they have been named panel1, panel2, ect.... I am needing to know how I can assign the panels to a 2D Array like 'chessBoardPanels[0,0]' this would allow me to actually control the backgrounds of the panels with a command like:
chessBoardPanels[0,0].Background=Color.Black;
But it says I need a some sort of object reference.
I would rather go for something like this
int numBlocks = 8;
Panel[,] chessBoardPanels = new Panel[numBlocks, numBlocks];
for (int iRow = 0; iRow < numBlocks; iRow++)
for (int iColumn = 0; iColumn < numBlocks; iColumn++)
{
Panel p = new Panel();
//set size
p.Size = new Size(50, 50);
//set back colour
p.BackColor = (iRow + (iColumn % 2)) % 2 == 0 ? Color.Black : Color.White;
//set location
p.Location = new Point(50 * iRow, 50 * iColumn);
chessBoardPanels[iRow, iColumn] = p;
this.Controls.Add(p);
}
This would allow you to create the Panels on the fly, without having to create them in the designer.
You will however have to work on a formula to handle the spacing for you.
EDIT
I have also added an example of how to space/set the panel blocks.
The syntax for creating such 2D array would be:
Panel[,] chessBoardPanels = new Panel[8, 8];
chessBoardPanels[0, 0] = panel1;
chessBoardPanels[0, 1] = panel2;
chessBoardPanels[0, 2] = panel3;
//...
chessBoardPanels[0, 7] = panel8;
chessBoardPanels[1, 0] = panel9;
//...
I kept a bool in my loop for the creation of my board to determine whether to use black or white as the background color. Before setting each field you must initiate the array (usually a two-dimensional one):
this.Fields = new PieceButton[Board.Size, Board.Size];
board = new Board(this);
for (int i = 0; i < Board.Size; i++)
{
for (int j = 0; j < Board.Size; j++)
{
this.Fields[i, j] = new PieceButton(even ? white : black, i, j);
this.Fields[i, j].Size = fieldSize;
this.Fields[i, j].Location = new Point(
i * PieceSize + widthOffset,
(Board.Size - j - 1) * PieceSize + heightOffset);
Fields[i, j].MouseDown += this.Piece_MouseDown;
this.Controls.Add(Fields[i, j]);
even = !even;
}
even = !even;
}

Dynamic UI, Loop not working correctly

Here is the code I'm using
It's supposed to create labels for each module name entered by a user and all the assessment names for that module under it. Should work with any number of modules and assessments. The problem is that it only shows assessments for the last module displayed.
dat.Modules and dat.Assessments are arraylists, each of them holds 4 elements with info about a module or an assessments, that is why i divide the count by 4.
private void testingButton_Click(object sender, EventArgs e)
{
int pos1 = 50;
int pos2 = 150;
int modLength = dat.Modules.Count;
modLength = modLength / 4;
int assessLength = 0;
int arrayData = 0;
int displayCount = 0;
for (int i = 0; i < modLength; i++)
{
this.moduleLabels.Add(new Label());
System.Drawing.Point pLabel1 = new System.Drawing.Point(50, pos1);
(moduleLabels[i] as Label).Location = pLabel1;
(moduleLabels[i] as Label).Size = new System.Drawing.Size(100, 13);
(moduleLabels[i] as Label).Text = dat.Modules[arrayData].ToString();
tabPage5.Controls.Add((moduleLabels[i] as Label));
String asd = dat.Modules[arrayData + 2].ToString();
Console.WriteLine(asd);
assessLength = int.Parse(asd);
pos2 = pos1 + 25;
for (int y = 0; y < assessLength; y++)
{
this.assessLabels.Add(new Label());
System.Drawing.Point pLabel2 = new System.Drawing.Point(70, pos2);
(assessLabels[y] as Label).Location = pLabel2;
(assessLabels[y] as Label).Size = new System.Drawing.Size(250, 13);
(assessLabels[y] as Label).Text = dat.Assessments[displayCount + 1].ToString() + " weights " + dat.Assessments[displayCount+2].ToString() +"%, Enter your mark:";
textboxComputer.Add(new TextBox());
System.Drawing.Point pText1 = new System.Drawing.Point(400, pos2);
(textboxComputer[y] as TextBox).Location = pText1;
(textboxComputer[y] as TextBox).Size = new System.Drawing.Size(20, 20);
tabPage5.Controls.Add(assessLabels[y] as Label);
tabPage5.Controls.Add(textboxComputer[y] as TextBox);
pos2 = pos2 + 25;
displayCount = displayCount + 4;
}
pos1 = pos2+25;
arrayData = arrayData + 4;
}
}
this is an example of what it displays
http://dc540.4shared.com/download/YI8IENYI/tsid20120501-211723-cbc785f9/asd.jpg
The first two modules should have their assessments listed. The first one doesn't display any. For Java it only displays the last one, out of 3 total for that module. And for the last Module "Another Module" it displays all assessments.
For each increment of i, y starts at 0. You then add new labels to assessLabels, but attempt to access the one you added by using assessLabels[y] which would usually yield the labels created for the previous value of i. This causes labels created for the first module to be reused by the next, and so forth.
A quick solution is not to use assessLabels[y] but assessLabels[assessLabels.Count - 1].
A better solution is to create a local variable for the labels, set their properties, and then add them to the list:
for (int y = 0; y < assessLength; y++)
{
Label assessLabel = new Label();
assessLabel.Location = ...;
// etc.
tabPage5.Controls.Add(assessLabel);
assessLabels.Add(assessLabel);
}
This would also remove the need to continuously cast the ArrayList members and unneeded access to the list.
PS. If assessLabels only contains objects of type Labels, consider using a List<Label> instead.

Categories