Drawing a label array in c# - 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]);

Related

Dynamically added labels disappear in runtime

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.

C# Window Form Application, how to efficiently create a dynamic panel on a window form

I would like to create a few panel dynamically in my window form application. Each panel will consist of 3 labels and one text box and one button. Now I know I can hard code this all at once by declaring each variable every time, but it takes a lot of coding and it is obviously not efficient at all.
So my question is: Is there a way to create pre-define panel dynamically where each time a panel is created will have a predefined layout setup already. So all i need to do is to add a panel, its location and size every time, and all the content(like labels, text-box and button) inside the panel are already setup with their location associated with the panel itself. Do I really have to create a class just for that?
Thanks in advance for read and taking your time.
Create Windows Forms control or user control, see http://msdn.microsoft.com/en-us/library/6hws6h2t.aspx
Create a user control, and place on it whatever you like (your labels). Expose public methods/properties of that control so you can control the contents of it. Place as many of those on the form as you like, they will all look and behave same.
Here is an example you can play with...
for (int i = 1; i < 5; i++)
{
var panel1 = new Panel() { Size = new Size(90, 80), Location = new Point(10, i * 100), BorderStyle = BorderStyle.FixedSingle };
panel1.Controls.Add(new Label() { Text = i.ToString(), Location = new Point(10, 20) });
panel1.Controls.Add(new Label() { Text = i.ToString(), Location = new Point(10, 40) });
panel1.Controls.Add(new Label() { Text = i.ToString(), Location = new Point(10, 60) });
Controls.Add(panel1);
}

How do I orderly generate controls underneath eachother?

I have a class which generates a form and controls. The controls vary between buttons, radio controls, check boxes and labels. The idea is to neatly create the form with a label above each control. The problem is that I cannot seem to find the formula or way to neatly organise/space them. It works fine when I have just text boxes, but I'm not sure how to handle larger controls, like check box lists. Here's an example of how I handle text boxes:
case "Text":
TextBox tbx = new TextBox();
tbx.Name = df.Value.Name;
tbx.Text = (df.Value.DefValue != null) ? df.Value.DefValue : "";
tbx.Location = new Point(lbl.Location.X, lbl.Location.Y + 20);
f.Controls.Add(tbx);
break;
Mind that this is all in a foreach loop. This is the part that precedes it (label):
if (i == 0)
{
lbl.Location = new Point(10, 10);
}
else
{
lbl.Location = new Point(10, (i * 50) + 10);
}
This neatly sorts the text boxes and labels out with an even spacing. Can anyone offer me some advice on how to handle different controls? I want to place them underneath eachother but keep at least 10 pixels spacing from the bottom of each control to the top of the next label.
Thank you in advance.
Use a tablelayout. You can take a look at how the designer does it in the code behind file.
For the spacing, fill in the "margin" property of your controls. 5 on top and 5 at the bottom should do it.

Adding an Array of labels to a Panel

I'm trying to add an array of labels to a panel in my Form.
I chose a label because I could set colors for the text.
If there is a better way, please let me know.
The code below runs fine but will only display one label.
I set a breakpoint and looked at the array before adding and all the
elements are there.
However, only one label actually shows up on the Panel.
Here's the code.
int y = 0;
int index = 0;
Label[] labels = new Label[10];
//Add Spareboard Employees to Spare List
foreach (Employee employee in EmployeeList)
{
labels[index] = new Label();
labels[index].Text = employee.Name;
labels[index].ForeColor = Color.Red;
labels[index].Location = new Point(0, y);
y = y + 10;
++index;
}
// Add the Label control to the form.
SparePanel.Controls.AddRange(labels);
Thanks in advance
The default size of the label is too big and each label's bottom is covering up the top of the label below it. You should add something like this:
labels[index].Size = new Size(50, 12);
maybe
Label[] labels = new Label[10];
needs to be
Control[] labels = new Control[10];
As far as I know, you need to implement the IEnumerable Interface and IEnumerate.Compare() method too, in order to iterate a foreach loop over your Employee object.
public class Employee : IEnumerator
{
//Implement IEnumerate method here
}
I'm not that experienced though so don't take my word for it! I would put more detailed code but I don't have it to hand.
Another possibility (which you were also looking for) is to draw the strings directly on the UI without adding controls. Do it during the paint event of the panel.
private void SparePanel_Paint(object sender, PaintEventArgs e)
{
using (SolidBrush empBrush = new SolidBrush(Color.Red))
{
int y = 0;
foreach (Employee employee in EmployeeList)
{
e.Graphics.DrawString(employee.Name, ((Panel)sender).Font, empBrush, 0, y);
y += 10;
}
}
}

Add and remove the UserControl dynamically

I have UserControl that holds Infragistics Graph control. On the TreeView sub node's right click, I have context menu as "Create Graph". This will create the new graph. This is about what i going to do.
I have confusion about what layout to use. Whether FlowLayoutPanel or TableLayoutPanel or anything else. If only one graph is add --> graph has to occupy the full form. If two graph are added --> two graph's has to split the space and so on.This is only in the format of one after another. ie First graph at top, second is below to first ..so on.
If UserControl is manually changed it should not affect the size where we displaying.
This is the WinForm. Currently i using FlowLayoutPanel, i creating panel with the constant size and added the UserControl with DockStyle.Fill. Then i added the Panel to the FlowLayoutPanel.
GraphUserControl usr = new GraphUserControl();
usr.Dock = DockStyle.Fill;
Panel pnl = new Panel();
pnl.Controls.Add(usr);
flowLayoutpnl.Controls.Add(pnl);
What is the best approach to do this?.
A TableLayoutPanel is probably your best choice, as the row heights can be set to a percentage value.
private void AddControl(Control ctl)
{
tableLayoutPnl.RowCount += 1;
tableLayoutPnl.RowStyles.Add(
new RowStyle(SizeType.Percent, 100F / tableLayoutPnl.RowCount));
ctl.Dock = DockStyle.Fill;
tableLayoutPnl.Controls.Add(ctl, 0, tableLayoutPnl.RowCount - 1);
foreach (RowStyle rs in tableLayoutPnl.RowStyles)
{
rs.Height = 100F / tableLayoutPnl.RowCount;
}
}
You can then call this as follows:
GraphUserControl usr = new GraphUserControl();
AddControl(usr);

Categories