0

I'm new here to Stack Overflow so please excuse any improper form/etiquette. Thanks!

EDIT: I guess my questions is not about how to fix the NullReference Exception, but rather how to deal with it not correctly "Exiting" the combobox when I click outside of it.

I am having an issue with my DataGridViewComboBoxCell setup that I am using. First of all, I have a datagridview that contains 3 columns which, upon the user enabling editing, populates the cells with a DataGridViewComboBoxCell. In each row, These 3 cells are dependent on selected item in the previous cell(except for the first ComboBoxCell). The issue I am having is if I click on the first ComboBox and I let it show the drop down list but I don't actually select anything and I move to the next ComboBoxCell and try to click it to view its list of items it stops the program and creates an error for "NullReference Exception was unhandled". This exception comes up under "static void Main()" at Application.Run(new MainForm());

Code that handles changing ComboBox selected index which should auto populate the other ComboBoxes.

private void LoadRules_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {

        DataGridViewComboBoxEditingControl cbx = e.Control as DataGridViewComboBoxEditingControl;
        if (cbx != null)
        {

            if (this.LoadRulesDataGridView.Columns[LoadRulesDataGridView.CurrentCell.ColumnIndex].Name.Equals("OEM"))
            {
                ComboBox cmbprocess = e.Control as ComboBox;


                cmbprocess.SelectedIndexChanged += new EventHandler(OEMBox_SelectedIndexChanged);
                cmbprocess.SelectedIndexChanged += new EventHandler(ModelBox_SelectedIndexChanged);
            }
        }

    }

    private void OEMBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        NetMonDB.DBManager dbConn = new NetMonDB.DBManager(ConnStr, this.LogWarning, this.LogError);
        ComboBox cmbprocess = (ComboBox)sender;

        int row = this.LoadRulesDataGridView.CurrentCell.RowIndex;
        string OEM = cmbprocess.SelectedItem.ToString();
        this.RulesGridModels(row, cmbprocess, dbConn, OEM);//this method gets the required info from the database and loads it into the ComboBox

        cmbprocess.SelectedIndexChanged -= new EventHandler(OEMBox_SelectedIndexChanged);
    }

    private void ModelBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        NetMonDB.DBManager dbConn = new NetMonDB.DBManager(ConnStr, this.LogWarning, this.LogError);
        ComboBox cmbprocess = (ComboBox)sender;

        int row = this.LoadRulesDataGridView.CurrentCell.RowIndex;
        string Model = cmbprocess.SelectedItem.ToString();
        string OEM = cmbprocess.SelectedItem.ToString();
        this.RulesGridOSVersions(row, cmbprocess, dbConn, OEM, Model);//this method gets the required info from the database and loads it into the ComboBox

        cmbprocess.SelectedIndexChanged -= new EventHandler(ModelBox_SelectedIndexChanged);
    }

Methods that update the ComboBoxes.

private void RulesGridModels(int r, ComboBox comboBox, NetMonDB.DBManager dbConn, string rowOEM)
    {
        //MessageBox.Show(this.LoadRulesDataGridView.Rows[0].Cells[4].Value.ToString());
        DataGridViewComboBoxCell cbo = new DataGridViewComboBoxCell();

        for (int i = 0; i < comboBox.Items.Count; i++)
        {
            cbo.Items.AddRange(comboBox.Items[i]);
        }
        try
        {
            cbo.Items.Clear();
            cbo.Items.AddRange("");
            if (this.LoadRulesDataGridView.Rows[r].Cells[4].Value == null)
                this.LoadRulesDataGridView.Rows[r].Cells[4].Value = "";

            NetMonDB.Phone OEMPhone = dbConn.getOEMId(rowOEM);
            foreach (NetMonDB.Phone phone in dbConn.getModel(OEMPhone))
            {
                cbo.Items.Add(phone.Model);
            }
            this.LoadRulesDataGridView.Rows[r].Cells[5] = cbo;
        }
        catch (Exception e)
        {
            LogError("RulesGridModels", e.ToString());
        }
    }

    private void RulesGridOSVersions(int r, ComboBox comboBox, NetMonDB.DBManager dbConn, string rowOEM, string rowModel)
    {
        DataGridViewComboBoxCell cbo = new DataGridViewComboBoxCell();

        for (int i = 0; i < comboBox.Items.Count; i++)
        {
            cbo.Items.AddRange(comboBox.Items[i]);
        }
        try
        {

            cbo.Items.Clear();
            cbo.Items.AddRange("");
            NetMonDB.Phone CurrentPhone = dbConn.getOEMId(rowOEM);
            CurrentPhone.Model = rowModel;
            foreach (NetMonDB.Phone phone in dbConn.getOSVersion(CurrentPhone))
            {
                cbo.Items.Add(phone.OSVersion);
            }
            this.LoadRulesDataGridView.Rows[r].Cells[6] = cbo;
        }
        catch (Exception e)
        {
            LogError("RulesGridOSVersions", e.ToString());
        }

    }

Where the exception is caught.

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());//Crashes at this Point
    }
Programmer
  • 449
  • 5
  • 20

1 Answers1

3

I had the same problem in a situation like this, What I found as a solution of this problem is to use SelectionChangeCommitted instead of SelectedIndexChanged event for combobox.

Abhishek Chaubey
  • 2,767
  • 1
  • 15
  • 24