Search code examples
c#winformsdatagridviewdatagridviewcomboboxcell

ComboBox added programmatically to DataGridView cell not expanding on cell click


I have a DataGridView in a C# WinForms project in which, when the user clicks on certain DGV cells, the cell changes to a DataGridViewComboBoxCell and the ComboBox is populated with some values for the user to select. Here's the form code for the DataGridView_Click event:

private void dgvCategories_Click(Object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 5 && !(dgvCategories.Rows[e.RowIndex].Cells[e.ColumnIndex].GetType().Name == "DataGridViewComboBoxCell"))
    {
        // Bind combobox to dgv and than bind new values datasource to combobox
        DataGridViewComboBoxCell cboNewValueList = new DataGridViewComboBoxCell();

        // Get fields to build New Value query
        List<string> lsNewValuesResult = new List<string>();
        string strCategory = dtCategories.Rows[e.RowIndex][1].ToString();
        string strCompanyName = cboSelectCompany.Text;
        string strQueryGetNewValuesValidationInfo = "SELECT validationdb, validationtable, validationfield, validationfield2, validationvalue2" +
                                                " FROM masterfiles.categories" +
                                                " WHERE category = @category";
                                                //" WHERE category = '" + strCategory + "'";

        // Pass validation info query to db and return list of New Values
        db getListOfNewValues = new db();
        lsNewValuesResult = getListOfNewValues.GetNewValuesList(strQueryGetNewValuesValidationInfo, strCategory, strCompanyName);

        //Populate the combobox with the list of New Values
        foreach (string strListItem in lsNewValuesResult)
        {
            cboNewValueList.Items.Add(strListItem);
        }

        // 
        dgvCategories[e.ColumnIndex, e.RowIndex] = cboNewValueList;

    }
}

Here's the code in the db class that populates the ComboBox (this likely isn't necessary to include for the purposes of this question, but for the sake of completeness, I'm including it, in case is it relevant):

public List<string> GetNewValuesList(string strValidationInfoQuery, string strCategory, string strCompanyName)
{
    List<string> lsValidationInfo = new List<string>();
    List<string> lsNewValuesList = new List<string>();

    using (NpgsqlConnection conn = new NpgsqlConnection(connString))
    using (NpgsqlCommand cmd = new NpgsqlCommand(strValidationInfoQuery, conn))
    {
        cmd.Parameters.AddWithValue("category", strCategory);

        conn.Open();

        using (NpgsqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                int intReaderIndex;
                for (intReaderIndex = 0; intReaderIndex <= reader.FieldCount - 1; intReaderIndex++)
                {

                    // reader indexes 3 & 4 correspond to categories.validationfield2 and validationvalue2, which can be null
                    if (string.IsNullOrEmpty(reader[intReaderIndex].ToString()))
                    {
                        lsValidationInfo.Add("");
                    }
                    else
                    {
                        lsValidationInfo.Add(reader.GetString(intReaderIndex));
                    }
                    //Console.WriteLine("reader index " + intReaderIndex + ": " + reader.GetString(intReaderIndex));
                }
            }
        }
    }

    string strValidationDb = lsValidationInfo[0];
    string strValidationTable = lsValidationInfo[1];
    string strValidationField = lsValidationInfo[2];
    string strValidationField2 = lsValidationInfo[3];
    string strValidationValue2 = lsValidationInfo[4];

    string strQueryGetNewValues = "SELECT DISTINCT " + strValidationField +
                        " FROM " + strValidationDb + "." + strValidationTable +
                        " WHERE company_id = (SELECT id FROM company WHERE name = '" + strCompanyName + "')";

    if (!string.IsNullOrEmpty(strValidationField2) && !string.IsNullOrEmpty(strValidationValue2)) strQueryGetNewValues += " AND " + strValidationField2 + " = '" + strValidationValue2 + "'";

    strQueryGetNewValues += " ORDER BY " + strValidationField;

    using (NpgsqlConnection conn = new NpgsqlConnection(connString))
    using (NpgsqlCommand cmd = new NpgsqlCommand(strQueryGetNewValues, conn))
    {
        conn.Open();

        using (NpgsqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                int intReaderIndex;
                for (intReaderIndex = 0; intReaderIndex <= reader.FieldCount - 1; intReaderIndex++)
                {
                    // reader indexes 3 & 4 correspond to categories.validationfield2 and validationvalue2, which can be null
                    if (string.IsNullOrEmpty(reader[intReaderIndex].ToString()))
                    {
                        lsNewValuesList.Add("");
                    }
                    else
                    {
                        lsNewValuesList.Add(reader.GetString(intReaderIndex));
                    }
                    Console.WriteLine("reader index " + intReaderIndex + ": " + reader.GetString(intReaderIndex));
                }
            }
        }
    }

    return lsNewValuesList;
}

The combobox is getting populated, as I can access the items in lsNewValuesResult in the _Click method. The DGV Edit Mode is set to EditOnEnter. I tried EditOnKeystroke, but that didn't cause the combobox to expand on mouse click.

This is what the combobox looks like when the cell is clicked on and the CBO is populated and added to the DGV cell:

enter image description here

That's after I clicked each of the two cells.

[RESOLVED]

See my Answer below.

Unfortunately solving this revealed a new issue.


Solution

  • I'm about to publicly admit that I'm stupid:

    For design and functionality reasons that are required for this project, I am manually setting the widths and names of the DGV's columns, and I also need the 2nd through 4th columns ReadOnly = true. Well, I inadvertently set the 5th column - the column that this question is about to ReadOnly = true as well.

    Thank you all for your attempts at answering. This just serves to remind us how something so simple can cause a seemingly big issue and is so easy to overlook!