Add ComboBoxes in runtime based on user input, how?

S

svein.erik.storkas

I'm creating an application where the user first selects a number from
a combobox. Based on his choice of number, ComboBoxes and buttons are
to be created (at runtime of course).

Let's say that the ComboBox is to be named cboTeam and the index number
(cboTeam1, cboTeam2 ...) It is also to be attached inside a specific
tabpage. How can I do this?

Some code:

//The button that gets the number the user choose:
private void cmdGenerateInputBoxes_Click(object sender, EventArgs e)
{
ReadXmlAndFillCombo( (string)cboNumberOfTeams.SelectedItem
);
}

//This is where I want to add x number of comboboxes:
public void ReadXmlAndFillCombo(string number)
{
int numberOfTeams = int.Parse(number);
//Read xml and fill the combobox(es)
fs = new FileStream(path, FileMode.Open, FileAccess.Read,
FileShare.ReadWrite);
xmldoc = new XmlDocument();
xmldoc.Load(fs);

for (int i = 0; i <= numberOfTeams; i++)
{ //I know this is wrong, but you get the idea.. :)
ComboBox cboTeam = new ComboBox();
this.Controls.Add(cboTeam);
this.tabNewCup.Controls.Add(cboTeam);
cboTeam.FormattingEnabled = true;
cboTeam.Location = new System.Drawing.Point(220, 424);
cboTeam.Name = "cboTeam";
cboTeam.Size = new System.Drawing.Size(121, 21);
cboTeam.TabIndex = 0;
cboTeam.Visible = true;
}

xmlnode = xmldoc.SelectNodes("(//spain/name)");

foreach (XmlNode node in xmlnode)
{
cboTeams.Items.Add(node.InnerText);
}
}

Hope someone can help me :)
 
M

Marc Gravell

Was there a /specific/ problem point / question?

That's /about/ right... the first thing you need to remember is that
"cboTeam" (as a variable) is only defined inside the loop; you should set
cboTeam.Name = "cboTeam" + i.ToString() [although this will be 0-based, not
1-based], and then to find the correct one, either cast the sender of an
event, or use this.Controls.Find("cboTeam5", true) to find the control.

You need to decide where the control sits; is it under "this", or under
"this.tabNewCup"; I suspect the latter, so drop the
this.Controls.Add(cboTeam); it can have only 1 parent.

The only other thing is that you might want to remove any options from the
last selection; this.tabNewCup.Controls.Clear() [before the for] may help,
but *strictly* speaking it would be better to Dispose() them as well. This
can mean taking a copy (tabNewCup.Controls.CopyTo(...)), then clearing the
collection, then enumerating the copy calling Dispose().

Oh, and you might have an off-by-one issue; <, not <=

Marc
 
S

svein.erik.storkas

Thanks for the reply Marc!

But I'm a newbie in programming really, if you could write some sample
code, I'd be really happy :)
 
S

svein.erik.storkas

When I use this code, no comboboxes appear..I have now decleared the
cboTeam variable as a public variable

for (int i = 0; i < numberOfTeams; i++)
{
cboTeam = new ComboBox();

this.tabNewCup.Controls.Add(cboTeam);
cboTeam.FormattingEnabled = true;
cboTeam.Location = new System.Drawing.Point(220, 424);
cboTeam.Name = "cboTeam" + i.ToString();
cboTeam.Size = new System.Drawing.Size(121, 21);
cboTeam.TabIndex = 0;
cboTeam.Visible = true;
}
 
M

Marc Gravell

Fair enough; try the two buttons, and changing values, etc.

In particular, look at the event handlers, as this is where the fun is.

Marc

using System;
using System.Windows.Forms;
class MyForm : Form
{
TabPage tabOne, tabTwo;
TabControl tabControl;
public MyForm() {
// setup the form; similar to InitializeComponent
tabControl = new TabControl();
tabOne = new TabPage("Tab 1");
tabTwo = new TabPage("Tab 2");
Button btnCreate = new Button();
Button btnLookup = new Button();
tabControl.TabPages.Add(tabOne);
tabControl.TabPages.Add(tabTwo);
tabControl.Dock = DockStyle.Fill;
btnCreate.Top = btnCreate.Margin.Top;
btnCreate.Text = "Create";
btnCreate.Click += new EventHandler(btnCreate_Click);
btnLookup.Top = btnCreate.Bottom + btnCreate.Margin.Bottom +
btnLookup.Margin.Top;
btnLookup.Text = "Lookup";
btnLookup.Click += new EventHandler(btnLookup_Click);
this.Controls.Add(tabControl);
tabOne.Controls.Add(btnCreate);
tabOne.Controls.Add(btnLookup);
}

void btnLookup_Click(object sender, EventArgs e)
{
Control[] found = this.Controls.Find("Combo5", true);
if (found.Length == 1)
{
this.Text = "Combo5.Text = " + found[0].Text;
}
else
{
this.Text = "Couldn't find Combo5";
}
}

void btnCreate_Click(object sender, EventArgs e)
{
SuspendLayout();
try
{
// cleanly dispose of any controls left on tab 2
Control[] oldControls = new Control[tabTwo.Controls.Count];
tabTwo.Controls.CopyTo(oldControls, 0);
tabTwo.Controls.Clear();
foreach (Control control in oldControls)
{
control.Dispose();
}

// add the new controls
object[] options = { "abc", "def", "ghi", "jkl", "mno", "pqr",
"stu", "vwx", "yz" };
int top = 0;
for (int i = 0; i < 10; i++)
{
ComboBox cbo = new ComboBox();
cbo.Items.AddRange(options);
cbo.Name = "Combo" + i.ToString();
top += cbo.Margin.Top;
cbo.Top = top;
top += cbo.Height + cbo.Margin.Bottom;
tabTwo.Controls.Add(cbo);
cbo.Text = "I'm " + cbo.Name;
cbo.SelectedIndexChanged += new
EventHandler(SomethingChanged);
cbo.TextChanged += new EventHandler(SomethingChanged);
}

// switch tab
tabControl.SelectedTab = tabTwo;
}
finally
{
ResumeLayout();
}
}

void SomethingChanged(object sender, EventArgs e)
{
ComboBox cbo = sender as ComboBox;
if (cbo == null) return; // didn't expect that!
object selected = cbo.SelectedItem;
if (selected == null)
{
this.Text = cbo.Name + " is now " + cbo.Text;
}
else
{
this.Text = cbo.Name + " is now " + selected.ToString();
}
}
}
class Program
{
static void Main()
{
using (MyForm form = new MyForm())
{
Application.Run(form);
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top