Adding multiple levels of dynamically created tabs - c#

I'm working on a WinForms application in which I have one static TabControl with a tab on which I need to add multiple levels of additional tabs. The number of these tabs will change depending on the data being loaded to the form.
I can add the first line of dynamic tabs tp the static tab like this for example:
TabControl tabControlWafers = new TabControl();
tabControlWafers.Dock = DockStyle.Fill;
int numwafers = wafers.Count();
for (int m = 0; m < numwafers; m++)
{
TabPage tabPage = new TabPage()
{
Name = wafers[m]
};
tabPage.Text = wafers[m].ToString();
tabControlWafers.TabPages.Add(tabPage);
}
tabPage1.Controls.Add(tabControlWafers);
My problem is that now I need to add another level of dynamically created tabs to each of the pages created above. After creating the next tabs like before:
TabControl tabControlStructure = new TabControl();
tabControlStructure.Dock = DockStyle.Fill;
int numstruct = structures.Count();
for (int n = 0; n < numstruct; n++)
{
TabPage tabPagestruct = new TabPage()
{
Name = structures[n]
};
tabPagestruct.Text = structures[n].ToString();
tabControlStructure.Controls.Add(tabPagestruct);
}
How do I get the tabs created here onto each of the first three tabs?

You should be able to accomplish what you need by iterating over the TabPageCollection in tabControlWafers.TabPages, then creating and adding one of your tabControlStructure objects at each iteration. See below for an example of how this could be done. Note the example assumes tabControlWafers has already been created.
foreach (TabPage tp in tabControlWafers.TabPages)
{
TabControl tabControlStructure = new TabControl()
{
Dock = DockStyle.Fill
};
int numstruct = structures.Count();
for (int i = 0; i < numstruct; i++)
{
TabPage tabPagestruct = new TabPage()
{
Name = structures[i],
Text = structures[i]
};
tabControlStructure.TabPages.Add(tabPagestruct);
}
tp.Controls.Add(tabControlStructure);
}
Edit:
Below is a generic example of the method by which I would generate the net nested TabPage structure. Note that if this were real, production code I would pull the addition of subpages off into its own method (something like addSubPages(TapPage parent, String[] names). This is nothing but a simple, paste and run example to give a better picture of what I am describing.
public Form1()
{
InitializeComponent();
TabControl tc1 = new TabControl()
{
Dock = DockStyle.Fill
};
for (int i = 0; i < 5; i++)
{
tc1.TabPages.Add(i.ToString());
}
foreach (TabPage tp in tc1.TabPages)
{
TabControl tc2 = new TabControl
{
Dock = DockStyle.Fill
};
for (int i = 0; i < 5; i++)
{
tc2.TabPages.Add(tp.Text + "." + i.ToString());
}
tp.Controls.Add(tc2);
foreach (TabPage tp2 in tc2.TabPages)
{
TabControl tc3 = new TabControl
{
Dock = DockStyle.Fill
};
for (int i = 0; i < 5; i++)
{
tc3.TabPages.Add(tp2.Text + "." + i.ToString());
}
tp2.Controls.Add(tc3);
}
}
this.Controls.Add(tc1);
}
The above example represents the constructor of an otherwise blank form that looks like the following:

Related

Form only recognizes one Groupbox property

I am trying to populate a run-time created Form.
First I create my text-properties that's supposed to each button
public static List<string> GetDialogs()
{
dialogs = new List<string>();
var tempString = "";
for (int i = 1; i <= FormSize.getHorizontalButtonCount(); i++)
{
for (int j = 1; j <= FormSize.getVerticalButtonCount(); j++)
{
//fx
tempString = $"{i}x{j*multiplier}";
dialogs.Add(tempString);
}
}
return dialogs;
}
and my list ends up like "1x5", "1x10", "1x15", "2x5" etc
Then I create all my Radiobuttons
public static List<RadioButton> CreateRadioButtons()
{
List<RadioButton> radioButtons = new List<RadioButton>();
for (int i = 0; i < FormSize.getRadioButtonCount(); i++)
{
var tempName = $"btn{i}";
radioButtons.Add(new RadioButton());
radioButtons[i].Name = tempName;
}
return radioButtons;
}
Which just creates a lot of buttons with some names like btn1 etc
Then I populate my Radiobutton-list with my dialog-list
private List<RadioButton> PopulateRadiobuttons()
{
dialogs = FormDialogs.GetDialogs();
List<RadioButton> tempRadioButtons = RadioButtonCreator.CreateRadioButtons();
for (int i = 0; i < FormSize.getRadioButtonCount(); i++)
{
tempRadioButtons[i].Text = dialogs[i];
}
return tempRadioButtons;
}
Now my Radiobuttons both contain a name like btn20 and a text like 4x30
Then I first populate a GroupBox with all my RadioButton elements before lastly populating my form with the groupbox.
public Form PopulateForm()
{
_box = new GroupBox();
radioButtons = PopulateRadiobuttons();
for (int i = 0; i < radioButtons.Count; i++)
{
_box.Controls.Add(radioButtons[i]);
}
_form.Controls.Add(_box);
return _form;
}
Besides all this, when I call this method to create a form it's only the first radiobutton that appears, the 1x5 one.
How could I go on about including all my buttons in my Form?
Here's what I do so far
private void Bt1_Click(object sender, Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs e)
{
FormCreator fm = new FormCreator();
f1 = fm.PopulateForm();
f1.Show();
}

Issue with Creating List of Link Labels

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);
}

Issue while creating Nested TableLayoutPanel

I am try to implement the Nested TableLayoutPanel. I am try to dynamically Create/load the child TableLayoutPanel inside parent TableLayoutPanel.
for this I take the parent TableLayoutPanel and draw it from visual studio toolbox.
one DropDownList for dynamically to create child TableLayoutPanel I assign some values to dropdownlist such as 2*2,2*3,3*3,4*4 when the selected index change is fire is draws the child TableLayoutPanel.
My code is below
private void cmbRowsColumns_SelectedIndexChanged(object sender, EventArgs e)
{
var selectedPair = new KeyValuePair<string, string>();
selectedPair = (KeyValuePair<string, string>)cmbRowsColumns.SelectedItem;
string[] rowcolumn = selectedPair.Value.Split('*');
string strRowCount = rowcolumn[0];
int rowCount = Convert.ToInt32(strRowCount);
string strColumnCount = rowcolumn[1];
int columnCount = Convert.ToInt32(strColumnCount);
DynamicallyGenerateColumn(rowCount, columnCount);
}
private void DynamicallyGenerateColumn(int rowCount, int columnCount)
{
parentTableLayoutPanel.Controls.Clear();
parentTableLayoutPanel.ColumnStyles.Clear();
parentTableLayoutPanel.RowStyles.Clear();
parentTableLayoutPanel.ColumnCount = columnCount;
parentTableLayoutPanel.RowCount = rowCount;
for (int i = 0; i < columnCount; i++)
{
parentTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
for (int j = 0; j < rowCount; j++)
{
if (i == 0)
{
parentTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
}
TableLayoutPanel objTableLayoutPanel = new TableLayoutPanel();
parentTableLayoutPanel.Controls.Add(objTableLayoutPanel, i, j);
}
}
}
but actually problem is when I create child TableLayoutPanel the formatting is not properly
I guess you want to fill each child panels So you need to add objTableLayoutPanel.Dock=DockStyle.Fill;
TableLayoutPanel objTableLayoutPanel = new TableLayoutPanel();
objTableLayoutPanel.Dock = DockStyle.Fill;
parentTableLayoutPanel.Controls.Add(objTableLayoutPanel, i, j);

Create a defined number of Label in a for loop

I want to create dynamically 10 Labels inside a for loop
string labelName;
for(int i = 0; i < 10; i++)
{
labeName = "Label" & i;
// Creata & Instanciate the label here, How ?
}
How would you create a bunch of objects which weren't UI elements? Use a collection:
List<Label> labels = new List<Label>();
for (int i = 0; i < 10; i++)
{
Label label = new Label();
// Set properties here
labels.Add(label);
}
You'll presumably want to add these labels to a form or page or whatever too...
List<string> labelName = new List<string>();
for(int i = 0; i < 10; i++)
{
labeName.Add(string.Concat("Label", i));
}

How to point to control?

i've 6 label controls in a form: label1, label2...label6.
How to 'refer' to the control in a loop like this:
for (i=1;i<=6;i++) {
label[i].text = ...;
}
Thank you
Try,
Label []labels={Label1,Label2,Label3};
Here's another way:
for (int n = 1; n < 4; n++)
{
Control[] Temp = Controls.Find("Label" + n, false);
Temp[0].Text = n.ToString();
}
Let's assume this is WinForms and that your "labels" are controls - the Form has a Controls property, which is a collection of controls associated with that container, so, we ought to be able to use Linq to query this, get the controls of the type we want, then iterate them, as such:
using System.Linq;
var labels = from control in Controls where control is Label select control;
for (i = 1; i <= controls.Count; i++)
{
labels[i].text = i.ToString();
}
A little rough, but you aren't very specific - it should be a decent starting point if nothing else.
EDIT:
OK, I thought I'd take the time to look into it, and Form.Controls doesn't like being used in Linq (in that straightforward way, at least), so as an alternative, this should help:
private List<Label> GetLabels()
{
var result = new List<Label>();
foreach (var control in Controls)
{
if (control is Label)
{
result.Add(control as Label);
}
}
return result;
}
The above method could even be factored in a genericised way rather simply; but then you can proceed:
var labels = GetLabels();
for (int i = 0; i <= labels.Count; i++)
{
labels[i].Text = i.ToString();
}
You can implement something like this:-
int y = 0;
int index = 0;
Label[] labels = new Label[6];
foreach (Student std in StudentList)
{
labels[index] = new Label();
labels[index].Text = std.Name;
labels[index].ForeColor = Color.Red;
labels[index].Location = new Point(0, y);
labels[index].Size = new Size(50, 12);
y = y + 10;
++index;
}
// Add the Label control to the form.
mPanel.Controls.AddRange(labels);

Categories