1

I want to create a depend between two columns of each rows in the DataGridView. I add two columns (brands, models) runtime (select data from database). My goal is to load new items in models cell when brands cell changed. Fill the data:

private void autoOptionsForm_Load(object sender, EventArgs e)
{
    Connection.ds.Tables.Clear();
    Connection.adap = new SqlDataAdapter("SELECT * FROM autoOptions", Connection.conn);
    Connection.adap.Fill(Connection.ds, "autoOptions");
    aoGV.DataSource = Connection.ds.Tables[0];         
    // Additing ComboBox column
    DataGridViewComboBoxColumn carCB = new DataGridViewComboBoxColumn();
    carCB.Name = "Model";
    aoGV.Columns.Add(carCB);

    DataGridViewComboBoxColumn brandCB = new DataGridViewComboBoxColumn();
    brandCB.Name = "Brand";
    aoGV.Columns.Add(brandCB);
    foreach (DataGridViewRow row in aoGV.Rows) {
        if (row.Index == aoGV.Rows.Count - 1) continue;
        //Additing CB for Models
     SqlCommand cmd = new SqlCommand(@"SELECT Model FROM Cars WHERE 
                        Brand_ID = (SELECT Brand_ID FROM Cars WHERE id='" + row.Cells["Car_ID"].Value + "')", Connection.conn);
     SqlDataReader sqlReader = cmd.ExecuteReader();
     while (sqlReader.Read()) ((DataGridViewComboBoxCell)row.Cells["Model"]).Items.Add(sqlReader["Model"].ToString());

        //Current Model ComboBox
     cmd = new SqlCommand(@"SELECT Model FROM Cars WHERE id = "+ row.Cells["Car_ID"].Value, Connection.conn);
     sqlReader = cmd.ExecuteReader();
     sqlReader.Read();
     int iId = ((DataGridViewComboBoxCell)row.Cells["Model"]).Items.IndexOf(sqlReader["Model"].ToString());

     ((DataGridViewComboBoxCell)row.Cells["Model"]).Value = ((DataGridViewComboBoxCell)row.Cells["Model"]).Items[iId];

        //Additing CB for Brands
     cmd = new SqlCommand(@"SELECT Brand_name FROM Brands", Connection.conn);
      sqlReader = cmd.ExecuteReader();
      while (sqlReader.Read()) ((DataGridViewComboBoxCell)row.Cells["Brand"]).Items.Add(sqlReader["Brand_name"].ToString());

      cmd = new SqlCommand(@"SELECT Brand_name FROM Brands WHERE id = 
                             (SELECT Brand_ID FROM Cars WHERE id = " + row.Cells["Car_ID"].Value + ")", Connection.conn);
      sqlReader = cmd.ExecuteReader();
      sqlReader.Read();
      iId = ((DataGridViewComboBoxCell)row.Cells["Brand"]).Items.IndexOf(sqlReader["Brand_name"].ToString());
      ((DataGridViewComboBoxCell)row.Cells["Brand"]).Value = ((DataGridViewComboBoxCell)row.Cells["Brand"]).Items[iId];
    }
}

My way to solution in code:

private void aoGV_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (aoGV.Columns[aoGV.SelectedCells[0].ColumnIndex].Name != "Brand") return;
    DataGridViewRow row = aoGV.Rows[aoGV.SelectedCells[0].RowIndex];
    SqlCommand cmd = new SqlCommand(@"SELECT Model FROM Cars WHERE 
                        Brand_ID = (SELECT id FROM Brands WHERE Brand_name = '"+row.Cells["Brand"].Value.ToString()+"')", Connection.conn);
    SqlDataReader sqlReader = cmd.ExecuteReader();
    ((DataGridViewComboBoxCell)row.Cells["Model"]).Items.Clear();
    while (sqlReader.Read()) ((DataGridViewComboBoxCell)row.Cells["Model"]).Items.Add(sqlReader["Model"].ToString());
}

And I have an error when trying to Clear items of cell. Why this error occurs?(Adding columns performs manually in runtime). Is any another solution to solve the problem?

enter image description here

braX
  • 11,506
  • 5
  • 20
  • 33
Evgeny Gerbut
  • 390
  • 1
  • 4
  • 10

1 Answers1

1

I know this is an old question, but still an answer might help the next one.

I just had the same issue and a little debugging showed that the problem is the value variable of the object. The value variable holds the currently selected value of the combobox, but when you clear the items, then this value becomes invalid and that causes the error. Setting the value variable to null before clearing removes the error.