There are several ways to go about this task. The simplest way involves adding a single combobox to the DataGrid.Controls, and then selectively displaying it as needed when a combobox cell becomes the currentcell. All the work is done in a few event handlers and no overrides or derived classes are necessary. This technique is discussed in Microsoft KB article Q323167.
The other techniques require you to derive a columnstyle. Attached is a dropdown combobox sample (C#, VB) that shows how you can use a combobox in a datagrid. This implementation differs from other available columnstyle samples (gotdotnet.com and C# Corner ) in that it derives from DataGridTextBoxColumn. These other samples derive directly from DataGridColumnStyle, and thus have to add functionality that already exists in DataGridTextBoxColumn.
This derived DataGridTextBoxColumn does not implement a databound combobox where you can set its DataSource, DisplayMember, and ValueMember to bind the combobox to a foreign table. If you need such a combobox, there is another sample link referenced at the end of this FAQ that does implement such a databound combobox.
This sample just attempts to replace the TextBox member of DataGridTextBoxColumn with a standard ComboBox member. Only two overrides need to be handled along with 2 events to get a functional implementation.
Here are the notes from the code that list the 3 steps to add a combobox to your datagrid.
// Step 1. Derive a custom column style from DataGridTextBoxColumn // a) add a ComboBox member // b) track when the combobox has focus in Enter and Leave events // c) override Edit to allow the ComboBox to replace the TextBox // d) override Commit to save the changed data // Step 2 - Use the combo column style // Add 1 col with combo style DataGridComboBoxColumn ComboTextCol = new DataGridComboBoxColumn(); ComboTextCol.MappingName = ''custCity''; ComboTextCol.HeaderText = ''Customer Address''; ComboTextCol.Width = 100; ts1.GridColumnStyles.Add(ComboTextCol); // Step 3 - Additional setup for Combo style // a) make the row height a little larger to handle minimum combo height ts1.PreferredRowHeight = ComboTextCol.ColumnComboBox.Height + 3; // b) Populate the combobox somehow. It is a normal combobox, so whatever... ComboTextCol.ColumnComboBox.Items.Clear(); ComboTextCol.ColumnComboBox.Items.Add(''Chicago''); ComboTextCol.ColumnComboBox.Items.Add(''Corvallis''); ComboTextCol.ColumnComboBox.Items.Add(''Denver''); ComboTextCol.ColumnComboBox.Items.Add(''Great Falls''); ComboTextCol.ColumnComboBox.Items.Add(''Kansas City''); ComboTextCol.ColumnComboBox.Items.Add(''Los Angeles''); ComboTextCol.ColumnComboBox.Items.Add(''Raleigh''); ComboTextCol.ColumnComboBox.Items.Add(''Washington''); // c) set the dropdown style of the combo... ComboTextCol.ColumnComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
Databound ComboBox Sample
To use a databound combobox, you have to add overrides for SetColumnValueAtRow and GetColumnValueAtRow to switch the DisplayMember and ValueMember as you get and set the data from the underlying table. Also, you cannot have the ComboBox bound with the same BindingContext to the same datasource as the datagrid. You can download a working project (C#, VB) that implements a databound combobox in a datagrid.
Thanks to Gerald Walsh for his suggestion to use the ComboBox.SelectionChangeCommitted event to set the editing flag within our derived columnstyle class.