title: Updating DataGridView via ComboBox Selection
body: <p>I have a <code>DataGridView</code> (called <code>SummaryDataGrid</code>) in a Windows Form Class (called <code>SummaryForm</code>) that I am trying to update programmatically via a <code>ComboBox</code> drop-down selection (called YearComboBox). <code>SummaryDataGrid</code> is not editable by the user, and it is simply used to display information in a spreadsheet-like manner. I want to be able to use <code>YearComboBox</code> for the user to select the year and then for <code>SummaryDataGrid</code> to update its values based on that year selection. You can see a screencap of the <code>SummaryForm</code> at the link below, showing <code>SummaryDataGrid</code> populated by the year 2020.</p>
  <p><a href="https://i.stack.imgur.com/Ie03i.png" rel="nofollow noreferrer">SummaryForm view</a></p>
  <p><code>YearComboBox</code> is not data-bound, and neither is <code>SummaryDataGrid</code>. To populate <code>SummaryDataGrid</code> programmatically, I do so by creating <code>DataGridViewRows</code> in <code>SummaryForm</code> and then populate the data by pulling from my SQL Database using functions defined in my <code>MainForm</code>, which in turn use functions defined in my Dataset that is linked to my <code>SQL Server</code> that I host. Some code examples can be found below.</p>
  <pre><code>public partial class SummaryForm : Form
  {
      private DataGridViewRow JanuaryRow = new DataGridViewRow();
      private DataGridViewRow FebruaryRow = new DataGridViewRow();
      private DataGridViewRow MarchRow = new DataGridViewRow();
      private DataGridViewRow AprilRow = new DataGridViewRow();
      private DataGridViewRow MayRow = new DataGridViewRow();
      private DataGridViewRow JuneRow = new DataGridViewRow();
      private DataGridViewRow JulyRow = new DataGridViewRow();
      private DataGridViewRow AugustRow = new DataGridViewRow();
      private DataGridViewRow SeptemberRow = new DataGridViewRow();
      private DataGridViewRow OctoberRow = new DataGridViewRow();
      private DataGridViewRow NovemberRow = new DataGridViewRow();
      private DataGridViewRow DecemberRow = new DataGridViewRow();
      private DataGridViewRow TotalRow = new DataGridViewRow();
      private DataGridViewRow AverageRow = new DataGridViewRow();
  
      private int year = DateTime.Today.Year;
      ...
      // form load event handler
      private void SummaryForm_FormLoad(Object sender, EventArgs e)
      {
          YearComboBox.Text = year.ToString();
  
          JanuaryRow.CreateCells(SummaryDataGrid);
          FebruaryRow.CreateCells(SummaryDataGrid);
          MarchRow.CreateCells(SummaryDataGrid);
          AprilRow.CreateCells(SummaryDataGrid);
          MayRow.CreateCells(SummaryDataGrid);
          JuneRow.CreateCells(SummaryDataGrid);
          JulyRow.CreateCells(SummaryDataGrid);
          AugustRow.CreateCells(SummaryDataGrid);
          SeptemberRow.CreateCells(SummaryDataGrid);
          OctoberRow.CreateCells(SummaryDataGrid);
          NovemberRow.CreateCells(SummaryDataGrid);
          DecemberRow.CreateCells(SummaryDataGrid);
          TotalRow.CreateCells(SummaryDataGrid);
          AverageRow.CreateCells(SummaryDataGrid);
  
          // populate january row
          JanuaryRow.Cells[0].Value = &quot;January&quot;;
          JanuaryRow.Cells[1].Value = MainFormInstance.BillsOfSaleCountMonth(1, year);
          JanuaryRow.Cells[2].Value = MainFormInstance.BillsOfSaleCashMonth(1, year);
          JanuaryRow.Cells[3].Value = MainFormInstance.BillsOfSaleCreditMonth(1, year);
          JanuaryRow.Cells[4].Value = Convert.ToDecimal(JanuaryRow.Cells[2].Value) + Convert.ToDecimal(JanuaryRow.Cells[3].Value);
          JanuaryRow.Cells[5].Value = MainFormInstance.CashMonth(1, year);
          JanuaryRow.Cells[6].Value = MainFormInstance.CardMonth(1, year);
          JanuaryRow.Cells[7].Value = MainFormInstance.MonthCP(1, year);
          JanuaryRow.Cells[8].Value = MainFormInstance.ExpensesMonthCP(1, year) + MainFormInstance.BillsOfSaleCashMonth(1, year);
          JanuaryRow.Cells[9].Value = Convert.ToDecimal(JanuaryRow.Cells[7].Value) - Convert.ToDecimal(JanuaryRow.Cells[8].Value);
          JanuaryRow.Cells[10].Value = MainFormInstance.MonthCF(1, year);
          JanuaryRow.Cells[11].Value = MainFormInstance.ExpensesMonthCF(1, year);
          JanuaryRow.Cells[12].Value = Convert.ToDecimal(JanuaryRow.Cells[10].Value) - Convert.ToDecimal(JanuaryRow.Cells[11].Value);
          JanuaryRow.Cells[13].Value = MainFormInstance.ExpensesMonthGeneral(1, year);
          JanuaryRow.Cells[14].Value = Convert.ToDecimal(JanuaryRow.Cells[5].Value) + Convert.ToDecimal(JanuaryRow.Cells[6].Value);
          JanuaryRow.Cells[15].Value = Convert.ToDecimal(JanuaryRow.Cells[8].Value) + Convert.ToDecimal(JanuaryRow.Cells[11].Value) + Convert.ToDecimal(JanuaryRow.Cells[13].Value);
          JanuaryRow.Cells[16].Value = Convert.ToDecimal(JanuaryRow.Cells[14].Value) - Convert.ToDecimal(JanuaryRow.Cells[15].Value);
          SummaryDataGrid.Rows.Add(JanuaryRow);
          ...
      }
  
      // year combo box selection event handler
      private void SummaryForm_YearChanged(Object sender, EventArgs e)
      {
          year = int.Parse(YearComboBox.Text);
          PopulateSummaryDataGrid();
      }
  
      // populate the summary data grid
      private void PopulateSummaryDataGrid()
      {
          // stubbed
      }
  </code></pre>
  <p>I have defined a SelectedValueChanged Event Handler for <code>YearComboBox</code>, and initially tried moving the populating of each row into a separate function from the <code>FormLoad</code> event handler. The idea was for the <code>FormLoad</code> event handler to update the YearComboBox initial Text attribute from the year variable defined in SummaryForm, perform the <code>CreateCells()</code> calls for each row, and then call a separate void function to perform the populating. However, when debugging, the separate function would immediately reach the first JanuaryRow statement trying to edit the cell and would say that the index was -1 and therefore out of range. I tried just having the SelectedValueChanged event trigger the <code>FormLoad</code> event handler, but that didn't work either due to the row already being created and populated.</p>
  <p>So, my question is how can I just get this drop-down selection to change the year used by the statements in the <code>FormLoad</code> event handler (which works fine) and have it repopulate the DataGridView with the new values based on the updated year?</p>