0

I have multiple comboboxes on a tabpage on a tabcontrol on a form. Trying to loop through the controls has not worked (see this).

So, I tried to go at it from another angle: finding the controls based on their name. As an initial POC, I just wanted to brute force it by providing the name of one of the combo boxes that is empty at design time ("cmbxRow0Element1") and assign the items from cmbxRow0Element0 to it. But both this attempt:

Control ctrl = this.Controls["cmbxRow0Element1"];
ComboBox cmbx = ctrl as ComboBox;
var items = cmbxRow0Element0.Items.OfType<object>().ToArray();
cmbx.Items.Add(items);

...and this one:

Control ctrl = this.Controls["cmbxRow0Element1"];
ComboBox cmbx = ctrl as ComboBox;
foreach (Object item in cmbxRow0Element0.Items)
{
    cmbx.Items.Add(item);
}

...result in "System.NullReferenceException was unhandled _HResult=-2147467261 _message=Object reference not set to an instance of an object."

...on the call to cmbx.Items.Add()

Why???

I want it to eventually be something like:

string cmbxName;
int cmbxCount = getCountOfComboBoxes();
for (int i = 0; i < cmbxCount; i++)
{
    cmbxName = string.Format("cmbxRow0Element{0}", i);
    Control ctrl = this.Controls[cmbxName];
    ComboBox cmbx = ctrl as ComboBox;
    cmbx.Items.Add("Twain");
    cmbx.Items.Add("Steinbeck");
    cmbx.Items.Add("Saroyan");
    cmbx.Items.Add("Frost");
    cmbx.Items.Add("Hardy");
    cmbx.Items.Add("Stegner");
}
Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • Not sure exactly what you are trying to accomplish, but why not just make a `List` and add the items to each `Combobox`? – KSdev May 23 '14 at 18:01
  • That is basically what I'm trying to do; the problem is in getting each combobox programatically (I don't want to have to explicitly name each one - I *could*, but that seems kludgy and "unprofessional"). – B. Clay Shannon-B. Crow Raven May 23 '14 at 18:03
  • What you just added to your question is along the lines I would push you. Have the outside `for` loop iterate through however many `Combobox` you need to add. When you add one go into a `foreach` loop for the `List` you created and add each item. That will clear up the `cmbx.Items.Add*` that you have listed out. – KSdev May 23 '14 at 18:12

2 Answers2

2

Because cmbxRow0Element1 is not direct child element of your Form. Use NameOfYourTabControl.Controls["cmbxRow0Element1"], or more generally:

this.Controls.SelectMany(x => x.Controls).First(x => x.Name == "cmbxRow0Element1");
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
0

This is a work-in-progress, but it is functional:

string cmbxName;
int cmbxCount = getCountOfComboBoxes();
for (int i = 0; i < cmbxCount; i++)
{
    cmbxName = string.Format("cmbxRow0Element{0}", i);
    Control ctrl = this.tabPage1.Controls[cmbxName];
    ComboBox cmbx = ctrl as ComboBox;
    cmbx.Items.Add("Christopher Robbin");
    cmbx.Items.Add("Eeyore");
    cmbx.Items.Add("Kanga");
    cmbx.Items.Add("Owl");
    cmbx.Items.Add("Piglet");
    cmbx.Items.Add("Rabbit");
    cmbx.Items.Add("Roo");
    cmbx.Items.Add("Tigger (T-I-Double Guh-Er)");
    cmbx.Items.Add("Winnie-the-Pooh");
}

The initial problem was that this/the form could not see what was on the tab pages; even the tab Control did not. I had to get specific with a particular tab*Page* for it to work.

UPDATE

Here is a better version - still could use null-checking and other niceties:

// Names of comboboxes are of the pattern "cmbxRowNElementN" the first N runs from 0..11, the second from 0..5
// This assume that you really do have twelve tabPages named tabPageRow0...tabPageRow11, and that there are six comboboxes on each tabpage 
const int TABPAGE_COUNT = 12;
const int COMBOXES_PER_TABPAGE = 6;
string tabPageBaseName = "tabPageRow";
List<String> MilneMilieu = new List<string>() { "Christopher Robin", "Eeyore", "Kanga", "Owl", "Piglet", "Rabbit", "Roo", "Tigger (T, I, Double-Guh, Er)", "Winnie-the-Pooh" };
string tabPageName;
string cmbxName;

try
{
    for (int i = 0; i < TABPAGE_COUNT; i++)
    {
        tabPageName = string.Format("{0}{1}", tabPageBaseName, i);
        Control tabpageCtrl = this.tabControl1.Controls[tabPageName];
        TabPage tp = tabpageCtrl as TabPage;

        for (int j = 0; j < COMBOXES_PER_TABPAGE; j++)
        {
            cmbxName = string.Format("cmbxRow{0}Element{1}", i, j);
            Control cmbxCtrl = tp.Controls[cmbxName];
            ComboBox cmbx = cmbxCtrl as ComboBox;
            // While we're at it, hook it to the shared event handler (although doing this violates the "S" in SOLID)
            cmbx.SelectionChangeCommitted += cmbxRow0Element0_SelectionChangeCommitted;
            foreach (var imaginaryFriend in MilneMilieu)
            {
                cmbx.Items.Add(imaginaryFriend);
            }
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862