title: C# : Populate Combobox based on Another
body: <p>Ok don't chastise me until you fully read this.  I know how to populate a combobox based on the selectedindex of another combobox, and have tested the method I found and it works.</p>
  
  <p>I'm building an application for work and am trying to do a lot more than my test build so if this is a simple fix forgive me...  just learned C# like 3 weeks ago and have only made 1 application so far and it was very crude.</p>
  
  <p>So to my problem....  I'm using SqlCE to store basic data for my forms.</p>
  
  <p>I have a BaseForm that stores variables and methods common to all of my forms.  Within this BaseForm I have all of my SqlCE content setup and ready for use with all of my sub-forms.
  They are setup as such:</p>
  
  <pre><code>internal SqlCeConnection dataConn = new SqlCeConnection(@"Data Source = |DataDirectory|\opi_data.sdf");
  internal SqlCeCommand command;
  internal SqlCeDataReader drDataSet;
  
  internal void openDataConnection() // Opens a connection to the data tables 
          {
              try
              {
                  if(dataConn.State == ConnectionState.Closed)
                      dataConn.Open();
              }
              catch(SqlCeException ex)
              {
                  MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
              }
          }
  </code></pre>
  
  <p>What I'm trying to do is populate two comboboxes, the first or parent box is a Bind Type, this stores the types of Binds that we carry.  It is setup as such:
  In the BaseForm:</p>
  
  <pre><code>internal void populateComboBox(string boxCommand, string itemsAdding, ComboBox comboBox) // Auto populates a combo box 
  {
      comboBox.Items.Clear();
      openDataConnection();
      try
      {
          command = new SqlCeCommand(boxCommand, dataConn);
  
          drDataSet = command.ExecuteReader();
          while (drDataSet.Read())
          {
              comboBox.Items.Add(drDataSet[itemsAdding].ToString());
              comboBox.SelectedIndex = 0;
          }
      }
      catch (Exception ex)
      {
          MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      finally
      {
          dataConn.Close();
      }
  }
  
  internal void populateComboBox(string boxCommand, string itemsAdding, int typeSelector, ComboBox comboBox) // Auto populate a combo box based on another 
  {
      comboBox.Items.Clear();
      openDataConnection();
      try
      {
          command = new SqlCeCommand(boxCommand + " WHERE TypeID = @type ORDER BY Id", dataConn);
          command.Parameters.AddWithValue("@type", typeSelector);
  
          drDataSet = command.ExecuteReader();
          while (drDataSet.Read())
          {
              comboBox.Items.Add(drDataSet[itemsAdding].ToString());
              comboBox.SelectedIndex = 0;
          }
      }
      catch (Exception ex)
      {
          MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      finally
      {
          dataConn.Close();
      }
  }
  </code></pre>
  
  <p>As you can see these are two overloaded methods.  The first is used to populate the parent combobox and the second is used to populate and filter the child combobox.</p>
  
  <p>Now in my form I have setup the comboboxes to populate as soon as the form is consturcted:</p>
  
  <pre><code>public partial class JobLog : BaseForm
  {
          public JobLog()
          {
              InitializeComponent();
              jobLogSetup();
          }
          private void jobLogSetup() // Initially sets up the form for use 
          {
              populateComboBox("SELECT * FROM bindtypes ORDER BY Id", "Type", comboBox3); // Populate bind type combo box
              populateComboBox("SELECT * FROM bindsizes", "Size", 1, comboBox4); // Populate bind size combo box
          }
  }
  </code></pre>
  
  <p>The bind type (parent) combobox is comboBox3 and the bind size (child) combobox is comboBox4.</p>
  
  <p>This works beautifully...  As I have to use the same methods for other sets of comboboxes as well.  So to my problem:  The methods work perfectly, no matter where I call them they always update the comboboxes... except when I try to call them using and if statement or switch statement in the combobox_SelectedIndexChanged event....</p>
  
  <p>What I used previously and worked in my first application was a switch and thus I mimicked it here:</p>
  
  <pre><code>private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
  {
      switch (comboBox3.SelectedIndex)
      {
          case 0:
              populateComboBox("SELECT * FROM bindsizes", "Size", 1, comboBox4);
              break;
          case 1:
              populateComboBox("SELECT * FROM bindsizes", "Size", 2, comboBox4);
              break;
          case 2:
              populateComboBox("SELECT * FROM bindsizes", "Size", 3, comboBox4);
              break;
          case 3:
              populateComboBox("SELECT * FROM bindsizes", "Size", 4, comboBox4);
              break;
          case 4:
              populateComboBox("SELECT * FROM bindsizes", "Size", 5, comboBox4);
              break;
          case 5:
              populateComboBox("SELECT * FROM bindsizes", "Size", 6, comboBox4);
              break;
      }
  }
  </code></pre>
  
  <p>However, when I use it in my newer application, I always get an error stating : "Invalid attempt to Read when reader is closed" as soon as I hit debug...  then I click OK and the form loads, only neither parent nor child combobox has been populated.  But if I don't use the switch or if statements and just set it some other way, I can populate them, but I can't get the child combobox to populate based on the parent comboboxes selection....</p>
  
  <p>I have toyed with this for the past 4 hours and quite frankly my brain is fried, so I moved on to another part of the application....  Can anyone tell me why this isn't working?</p>