How to prevent DataGridView ComboBox column text value from disappearing

John Rutherford 21 Reputation points
2023-02-08T07:13:01.2666667+00:00

Hi,

I have a Windows forms project in .Net Framework 4.7.2

I have a DatagridView (dgv) with 5 textbox columns columns + 1 ComboBoxColumn. The dgv textboxcolumns are bound to a BindingSource (bs4 of EntryModel type). The DatagridviwCombobox (tcode) column has the following 2 vlaues assigned to it;

tcode.Items.AddRange("AAA", "BBB");

private void DgvEntries_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)

{

    combo = e.Control as ComboBox;

    if (combo != null)

    {

        combo.SelectedIndexChanged -= new EventHandler(Combo_SelectedIndexChanged);

        combo.SelectedIndexChanged += Combo_SelectedIndexChanged;

    }

}

private void Combo_SelectedIndexChanged(object sender, EventArgs e)

{

    if (combo != null)

    {

        if (combo.SelectedIndex == 0)

        {

            EntryModel ent = (EntryModel)bs4.Current;

            ent.Rate = 0.1m;

        }

        else

        {

            EntryModel ent = (EntryModel)bs4.Current;

            ent.Rate = 0m;

        }

    }

}

I use the above code to get the SelectedIndex from the ComboBox and then update the bs4.current (bound EntryModel item) based on that result. This all seems to work fine with 3 of the textbox column values updating correctly as expected.

I have traced the SelectedIndex value for the combo through the code and it is set correctly up to the last } of the Combo_SelectedIndexChanged event. At that point, the value changes to -1 (ie blank) and the ComboBox text disappears.

Any assistance to stop the combobox text from disappearing this would be appreciated.

Thanks,

John

Developer technologies Windows Forms
Developer technologies C#
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Alan Farias 755 Reputation points
    2023-03-01T09:34:15.92+00:00

    To prevent the DataGridView ComboBox column text value from disappearing, you can try setting the DropDownStyle property of the DataGridViewComboBoxColumn to ComboBoxStyle.DropDown. This will allow users to enter text in the ComboBox even if it is not in the list of available items.

    You can set the DropDownStyle property in code by accessing the DataGridViewComboBoxColumn object and setting its DropDownStyle property:

    dgv.Columns["comboColumnName"].DefaultCellStyle = new DataGridViewCellStyle { NullValue = string.Empty }; (DataGridViewComboBoxColumn)dgv.Columns["comboColumnName"]).DropDownStyle = ComboBoxStyle.DropDown;
    

    Also, in the DgvEntries_EditingControlShowing event handler, you can try setting the EditingControl.Text property to the selected value of the ComboBox in case it is not already set:

    private void DgvEntries_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        if (e.Control is ComboBox combo)
        {
            combo.SelectedIndexChanged -= Combo_SelectedIndexChanged;
            combo.SelectedIndexChanged += Combo_SelectedIndexChanged;
    
            if (combo.DropDownStyle == ComboBoxStyle.DropDown)
            {
                combo.Text = combo.SelectedItem?.ToString() ?? string.Empty;
            }
        }
    }
    

    With these changes, the ComboBox column text value should not disappear when the ComboBox_SelectedIndexChanged event is fired.


    Please, if this answer is helpful, click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please let me know.

    0 comments No comments

  2. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-03-01T11:58:17.9+00:00

    I have a full working example here.

    • Data is read in from two database tables in one method in a class
    • The form assigns the DataTable returned to two BindingSource components and does configuration as per below.
    private void Setup()
    {
    
        CustomersDataGridView.AutoGenerateColumns = false;
    
        var (customerTable, colorTable) = DataOperations.LoadData();
    
    
        _colorBindingSource.DataSource = colorTable;
    
        ColorComboBoxColumn.DisplayMember = "ColorText";
        ColorComboBoxColumn.ValueMember = "ColorId";
        ColorComboBoxColumn.DataPropertyName = "ColorId";
    
        ColorComboBoxColumn.DataSource = _colorBindingSource;
    
        ColorComboBoxColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
    
    
        ItemTextBoxColumn.DataPropertyName = "Item";
        _customerBindingSource.DataSource = customerTable;
    
        bindingNavigator1.BindingSource = _customerBindingSource;
        CustomersDataGridView.DataSource = _customerBindingSource;
    
        CustomersDataGridView.EditingControlShowing += CustomersDataGridViewOnEditingControlShowing;
        ColorIdLabel.DataBindings.Add("Text", _customerBindingSource, "ColorId", true);
    }
    

    Get current ComboBox value using the BindingSource

    private void CurrentButton_Click(object sender, EventArgs e)
    {
        var customerRow = ((DataRowView)_customerBindingSource.Current).Row;
    
        var colorName = (_colorBindingSource.DataSource as DataTable).AsEnumerable()
            .FirstOrDefault(row => row.Field<int>("ColorId") == customerRow.Field<int>("ColorId"))
            .Field<string>("ColorText");
    
        MessageBox.Show(colorName);
    }
    

    Set the current value for the ComboBox

    private void SetCurrentColorButton_Click(object sender, EventArgs e)
    {
        DataRow currentRow = ((DataRowView)_customerBindingSource.Current).Row;
        currentRow.SetField("ColorId", 1); // set to red in this case
    }
    

    Screenshot

    figure2.png

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.