0

I want to show an combobox and show all its elements when users click the cell in the datatable.

The problem is when I click the cell, the combobox does not appear.

But after I click the second cell, the combobox in the first cell appears.

Then, I need to click the combobox twice to display all the elements.

What is the problem and how to solve it?

Here is my code.

private DataTable GetInfoTable()
{
    DataTable l_dtInfo = new DataTable();
    l_dtInfo .Columns.Add("Info", typeof(string));
    l_dtInfo .Rows.Add("11-20");
    l_dtInfo .Rows.Add("21-30");
    l_dtInfo .Rows.Add("31-40");
    return l_dtInfo ;
}  

private void editValue(object sender, DataGridViewCellValidatingEventArgs e)
{
    DataGridView grid = sender as DataGridView;

    if (e.ColumnIndex > -1)
    {
        DataGridViewComboBoxCell l_objGridDropbox = new DataGridViewComboBoxCell();
        grid[e.ColumnIndex, e.RowIndex] = l_objGridDropbox;
        l_objGridDropbox.DataSource = GetInfoTable();
        l_objGridDropbox.ValueMember = "Info";
        l_objGridDropbox.DisplayMember = "Info";

     }  
 }
Chan
  • 3,605
  • 9
  • 29
  • 60
  • Is this a `Windows Form App (.NET Framework)` solution or something else? If it IS a win forms solution, then I would think you would be getting an error on the line of code … `grid[e.ColumnIndex, e.RowIndex] = l_objGridDropbox;` … This assumes the `editValue` event is the grids `CellValidatingEvent` in which case the “re-entrant” error will get thrown on that line of code. Can you clarify? – JohnG Oct 19 '21 at 18:46
  • Also, the code will change ANY “edited” cell into a combo box?... Is this your intention as this is very odd? In addition, is it possible you have wired up the grids `DataError` and are ignoring/swallowing these errors? This is the only way the code will semi-work without errors. Again, can you clarify any of this? You comment that… _”the combobox does not appear”_ … and this would be true for any cell that originally was not a combo box cell as the event will not fire until the user “leaves” the cell. – JohnG Oct 19 '21 at 19:13
  • When an user clicks any cell in info column, I want a combobox appears for him to select value and show all elements without further click. What is the correct approach? – Chan Oct 20 '21 at 03:23
  • This is the website I read : https://www.c-sharpcorner.com/blogs/steps-to-add-combobox-inside-datagridview-window-form – Chan Oct 20 '21 at 03:42
  • There is a `DataGridViewComboBoxColumn` you could use and it would have the combo boxes there “before” the user clicks on the cell. To get the combo box to open in one click… try setting the grids “EditMode” to “EditOnEnter” … something like… `dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;` – JohnG Oct 20 '21 at 21:41

1 Answers1

1

The easier life (i.e. how MS intended you do it):

  • Add a DataSet type of file to your project
  • Open it so you see the design surface
  • Add a datatable representing your main data, e.g. Persons dataTable with Name(string) column, AgeRangeId (int) column; right click the surface, choose add>>datatable. Right click the table, add>>column etc
  • Add another table called AgeRanges, add an AgeRangeId(int) column and a DisplayText(string) column
  • Switch to forms designer, open DataSources window (hope youre using net framework, not net core!) from View menu>>Other windows
  • Drag the Persons node onto the form, DGV appears bound to a new bindingsource (at the bottom) which is bound to Persons datatable in the dataset that has appeared (at the bottom)
  • Click the [>] in the top right of the grid view to pop open its quick actions, choose edit columns
  • Change the AgeRange column to a combobox type one. Set the DataSource to the AgeRanges table, ValueMember to AgeRangeId, DisplayMember to DisplayText. DataMember should already be bound to AgeRangeId (in the Person table)
  • In code, in the constructor, fill in the AgeRange table like what you have there
private PersonForm() //constructor
{
    InitializeComponent();
 
    //whatever you chose to name your dataset, will affect this variable name
    someDataSetName.AgeRanges.AddAgeRangesRow(1, "11-20");
    someDataSetName.AgeRanges.AddAgeRangesRow(2, "21-30");
    someDataSetName.AgeRanges.AddAgeRangesRow(3, "31-40");

    //let's add some sample data to persons too
    someDataSetName.Persons.AddPersonsRow("John", 1);
    someDataSetName.Persons.AddPersonsRow("Mark", 3);
    someDataSetName.Persons.AddPersonsRow("Luke", 2);

}  

Run the project, and it should Just Work (TM).

Caius Jard
  • 72,509
  • 5
  • 49
  • 80