1 out of 3 rated this helpful - Rate this topic

DataGridViewComboBoxCell Class

Displays a combo box in a DataGridView control.

System.Object
  System.Windows.Forms.DataGridViewElement
    System.Windows.Forms.DataGridViewCell
      System.Windows.Forms.DataGridViewComboBoxCell

Namespace:  System.Windows.Forms
Assembly:  System.Windows.Forms (in System.Windows.Forms.dll)
public class DataGridViewComboBoxCell : DataGridViewCell

The DataGridViewComboBoxCell type exposes the following members.

  Name Description
Public method DataGridViewComboBoxCell Initializes a new instance of the DataGridViewComboBoxCell class.
Top
  Name Description
Public property AccessibilityObject Gets the DataGridViewCell.DataGridViewCellAccessibleObject assigned to the DataGridViewCell. (Inherited from DataGridViewCell.)
Public property AutoComplete Gets or sets a value indicating whether the cell will match the characters being entered in the cell with a selection from the drop-down list.
Public property ColumnIndex Gets the column index for this cell. (Inherited from DataGridViewCell.)
Public property ContentBounds Gets the bounding rectangle that encloses the cell's content area. (Inherited from DataGridViewCell.)
Public property ContextMenuStrip Gets or sets the shortcut menu associated with the cell. (Inherited from DataGridViewCell.)
Public property DataGridView Gets the DataGridView control associated with this element. (Inherited from DataGridViewElement.)
Public property DataSource Gets or sets the data source whose data contains the possible selections shown in the drop-down list.
Public property DefaultNewRowValue Gets the default value for a cell in the row for new records. (Inherited from DataGridViewCell.)
Public property Displayed Gets a value that indicates whether the cell is currently displayed on-screen. (Inherited from DataGridViewCell.)
Public property DisplayMember Gets or sets a string that specifies where to gather selections to display in the drop-down list.
Public property DisplayStyle Gets or sets a value that determines how the combo box is displayed when it is not in edit mode.
Public property DisplayStyleForCurrentCellOnly Gets or sets a value indicating whether the DisplayStyle property value applies to the cell only when it is the current cell in the DataGridView control.
Public property DropDownWidth Gets or sets the width of the of the drop-down list portion of a combo box.
Public property EditedFormattedValue Gets the current, formatted value of the cell, regardless of whether the cell is in edit mode and the value has not been committed. (Inherited from DataGridViewCell.)
Public property EditType Gets the type of the cell's hosted editing control. (Overrides DataGridViewCell.EditType.)
Public property ErrorIconBounds Gets the bounds of the error icon for the cell. (Inherited from DataGridViewCell.)
Public property ErrorText Gets or sets the text describing an error condition associated with the cell. (Inherited from DataGridViewCell.)
Public property FlatStyle Gets or sets the flat style appearance of the cell.
Public property FormattedValue Gets the value of the cell as formatted for display. (Inherited from DataGridViewCell.)
Public property FormattedValueType Gets the class type of the formatted value associated with the cell. (Overrides DataGridViewCell.FormattedValueType.)
Public property Frozen Gets a value indicating whether the cell is frozen. (Inherited from DataGridViewCell.)
Public property HasStyle Gets a value indicating whether the Style property has been set. (Inherited from DataGridViewCell.)
Public property InheritedState Gets the current state of the cell as inherited from the state of its row and column. (Inherited from DataGridViewCell.)
Public property InheritedStyle Gets the style currently applied to the cell. (Inherited from DataGridViewCell.)
Public property IsInEditMode Gets a value indicating whether this cell is currently being edited. (Inherited from DataGridViewCell.)
Public property Items Gets the objects that represent the selection displayed in the drop-down list.
Public property MaxDropDownItems Gets or sets the maximum number of items shown in the drop-down list.
Public property OwningColumn Gets the column that contains this cell. (Inherited from DataGridViewCell.)
Public property OwningRow Gets the row that contains this cell. (Inherited from DataGridViewCell.)
Public property PreferredSize Gets the size, in pixels, of a rectangular area into which the cell can fit. (Inherited from DataGridViewCell.)
Public property ReadOnly Gets or sets a value indicating whether the cell's data can be edited. (Inherited from DataGridViewCell.)
Public property Resizable Gets a value indicating whether the cell can be resized. (Inherited from DataGridViewCell.)
Public property RowIndex Gets the index of the cell's parent row. (Inherited from DataGridViewCell.)
Public property Selected Gets or sets a value indicating whether the cell has been selected. (Inherited from DataGridViewCell.)
Public property Size Gets the size of the cell. (Inherited from DataGridViewCell.)
Public property Sorted Gets or sets a value indicating whether the items in the combo box are automatically sorted.
Public property State Gets the user interface (UI) state of the element. (Inherited from DataGridViewElement.)
Public property Style Gets or sets the style for the cell. (Inherited from DataGridViewCell.)
Public property Tag Gets or sets the object that contains supplemental data about the cell. (Inherited from DataGridViewCell.)
Public property ToolTipText Gets or sets the ToolTip text associated with this cell. (Inherited from DataGridViewCell.)
Public property Value Gets or sets the value associated with this cell. (Inherited from DataGridViewCell.)
Public property ValueMember Gets or sets a string that specifies where to gather the underlying values used in the drop-down list.
Public property ValueType Gets or sets the data type of the values in the cell. (Overrides DataGridViewCell.ValueType.)
Public property Visible Gets a value indicating whether the cell is in a row or column that has been hidden. (Inherited from DataGridViewCell.)
Top
  Name Description
Public method AdjustCellBorderStyle Modifies the input cell border style according to the specified criteria. (Inherited from DataGridViewCell.)
Protected method BorderWidths Returns a Rectangle that represents the widths of all the cell margins. (Inherited from DataGridViewCell.)
Protected method ClickUnsharesRow Indicates whether the cell's row will be unshared when the cell is clicked. (Inherited from DataGridViewCell.)
Public method Clone Creates an exact copy of this cell. (Overrides DataGridViewCell.Clone().)
Protected method ContentClickUnsharesRow Indicates whether the cell's row will be unshared when the cell's content is clicked. (Inherited from DataGridViewCell.)
Protected method ContentDoubleClickUnsharesRow Indicates whether the cell's row will be unshared when the cell's content is double-clicked. (Inherited from DataGridViewCell.)
Protected method CreateAccessibilityInstance Creates a new accessible object for the DataGridViewCell. (Inherited from DataGridViewCell.)
Public method DetachEditingControl Removes the cell's editing control from the DataGridView. (Overrides DataGridViewCell.DetachEditingControl().)
Public method Dispose() Releases all resources used by the DataGridViewCell. (Inherited from DataGridViewCell.)
Protected method Dispose(Boolean) Releases the unmanaged resources used by the DataGridViewCell and optionally releases the managed resources. (Inherited from DataGridViewCell.)
Protected method DoubleClickUnsharesRow Indicates whether the cell's row will be unshared when the cell is double-clicked. (Inherited from DataGridViewCell.)
Protected method EnterUnsharesRow Indicates whether the parent row will be unshared when the focus moves to the cell. (Inherited from DataGridViewCell.)
Public method Equals(Object) Determines whether the specified Object is equal to the current Object. (Inherited from Object.)
Protected method Finalize Releases the unmanaged resources and performs other cleanup operations before the DataGridViewCell is reclaimed by garbage collection. (Inherited from DataGridViewCell.)
Protected method GetClipboardContent Retrieves the formatted value of the cell to copy to the Clipboard. (Inherited from DataGridViewCell.)
Public method GetContentBounds(Int32) Returns the bounding rectangle that encloses the cell's content area using a default Graphics and cell style currently in effect for the cell. (Inherited from DataGridViewCell.)
Protected method GetContentBounds(Graphics, DataGridViewCellStyle, Int32) Returns the bounding rectangle that encloses the cell's content area, which is calculated using the specified Graphics and cell style. (Overrides DataGridViewCell.GetContentBounds(Graphics, DataGridViewCellStyle, Int32).)
Public method GetEditedFormattedValue Returns the current, formatted value of the cell, regardless of whether the cell is in edit mode and the value has not been committed. (Inherited from DataGridViewCell.)
Protected method GetErrorIconBounds Returns the bounding rectangle that encloses the cell's error icon, if one is displayed. (Overrides DataGridViewCell.GetErrorIconBounds(Graphics, DataGridViewCellStyle, Int32).)
Protected method GetErrorText Returns a string that represents the error for the cell. (Inherited from DataGridViewCell.)
Protected method GetFormattedValue Gets the formatted value of the cell's data. (Overrides DataGridViewCell.GetFormattedValue(Object, Int32, DataGridViewCellStyle, TypeConverter, TypeConverter, DataGridViewDataErrorContexts).)
Public method GetHashCode Serves as a hash function for a particular type. (Inherited from Object.)
Public method GetInheritedContextMenuStrip Gets the inherited shortcut menu for the current cell. (Inherited from DataGridViewCell.)
Public method GetInheritedState Returns a value indicating the current state of the cell as inherited from the state of its row and column. (Inherited from DataGridViewCell.)
Public method GetInheritedStyle Gets the style applied to the cell. (Inherited from DataGridViewCell.)
Protected method GetPreferredSize Calculates the preferred size, in pixels, of the cell. (Overrides DataGridViewCell.GetPreferredSize(Graphics, DataGridViewCellStyle, Int32, Size).)
Protected method GetSize Gets the size of the cell. (Inherited from DataGridViewCell.)
Public method GetType Gets the Type of the current instance. (Inherited from Object.)
Protected method GetValue Gets the value of the cell. (Inherited from DataGridViewCell.)
Public method InitializeEditingControl Attaches and initializes the hosted editing control. (Overrides DataGridViewCell.InitializeEditingControl(Int32, Object, DataGridViewCellStyle).)
Protected method KeyDownUnsharesRow Indicates whether the parent row is unshared if the user presses a key while the focus is on the cell. (Inherited from DataGridViewCell.)
Public method KeyEntersEditMode Determines if edit mode should be started based on the given key. (Overrides DataGridViewCell.KeyEntersEditMode(KeyEventArgs).)
Protected method KeyPressUnsharesRow Indicates whether a row will be unshared if a key is pressed while a cell in the row has focus. (Inherited from DataGridViewCell.)
Protected method KeyUpUnsharesRow Indicates whether the parent row is unshared when the user releases a key while the focus is on the cell. (Inherited from DataGridViewCell.)
Protected method LeaveUnsharesRow Indicates whether a row will be unshared when the focus leaves a cell in the row. (Inherited from DataGridViewCell.)
Protected method MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Protected method MouseClickUnsharesRow Indicates whether a row will be unshared if the user clicks a mouse button while the pointer is on a cell in the row. (Inherited from DataGridViewCell.)
Protected method MouseDoubleClickUnsharesRow Indicates whether a row will be unshared if the user double-clicks a cell in the row. (Inherited from DataGridViewCell.)
Protected method MouseDownUnsharesRow Indicates whether a row will be unshared when the user holds down a mouse button while the pointer is on a cell in the row. (Inherited from DataGridViewCell.)
Protected method MouseEnterUnsharesRow Indicates whether a row will be unshared when the mouse pointer moves over a cell in the row. (Inherited from DataGridViewCell.)
Protected method MouseLeaveUnsharesRow Indicates whether a row will be unshared when the mouse pointer leaves the row. (Inherited from DataGridViewCell.)
Protected method MouseMoveUnsharesRow Indicates whether a row will be unshared when the mouse pointer moves over a cell in the row. (Inherited from DataGridViewCell.)
Protected method MouseUpUnsharesRow Indicates whether a row will be unshared when the user releases a mouse button while the pointer is on a cell in the row. (Inherited from DataGridViewCell.)
Protected method OnClick Called when the cell is clicked. (Inherited from DataGridViewCell.)
Protected method OnContentClick Called when the cell's contents are clicked. (Inherited from DataGridViewCell.)
Protected method OnContentDoubleClick Called when the cell's contents are double-clicked. (Inherited from DataGridViewCell.)
Protected method OnDataGridViewChanged Called when the DataGridView property of the cell changes. (Overrides DataGridViewCell.OnDataGridViewChanged().)
Protected method OnDoubleClick Called when the cell is double-clicked. (Inherited from DataGridViewCell.)
Protected method OnEnter Called when the focus moves to a cell. (Overrides DataGridViewCell.OnEnter(Int32, Boolean).)
Protected method OnKeyDown Called when a character key is pressed while the focus is on a cell. (Inherited from DataGridViewCell.)
Protected method OnKeyPress Called when a key is pressed while the focus is on a cell. (Inherited from DataGridViewCell.)
Protected method OnKeyUp Called when a character key is released while the focus is on a cell. (Inherited from DataGridViewCell.)
Protected method OnLeave Called when the focus moves from a cell. (Overrides DataGridViewCell.OnLeave(Int32, Boolean).)
Protected method OnMouseClick Called when the user clicks a mouse button while the pointer is on a cell. (Overrides DataGridViewCell.OnMouseClick(DataGridViewCellMouseEventArgs).)
Protected method OnMouseDoubleClick Called when the user double-clicks a mouse button while the pointer is on a cell. (Inherited from DataGridViewCell.)
Protected method OnMouseDown Called when the user holds down a mouse button while the pointer is on a cell. (Inherited from DataGridViewCell.)
Protected method OnMouseEnter Called when the mouse pointer moves over a cell. (Overrides DataGridViewCell.OnMouseEnter(Int32).)
Protected method OnMouseLeave Called when the mouse pointer leaves the cell. (Overrides DataGridViewCell.OnMouseLeave(Int32).)
Protected method OnMouseMove Called when the mouse pointer moves within a cell. (Overrides DataGridViewCell.OnMouseMove(DataGridViewCellMouseEventArgs).)
Protected method OnMouseUp Called when the user releases a mouse button while the pointer is on a cell. (Inherited from DataGridViewCell.)
Protected method Paint Paints the current DataGridViewComboBoxCell. (Overrides DataGridViewCell.Paint(Graphics, Rectangle, Rectangle, Int32, DataGridViewElementStates, Object, Object, String, DataGridViewCellStyle, DataGridViewAdvancedBorderStyle, DataGridViewPaintParts).)
Protected method PaintBorder Paints the border of the current DataGridViewCell. (Inherited from DataGridViewCell.)
Protected method PaintErrorIcon Paints the error icon of the current DataGridViewCell. (Inherited from DataGridViewCell.)
Public method ParseFormattedValue Converts a value formatted for display to an actual cell value. (Overrides DataGridViewCell.ParseFormattedValue(Object, DataGridViewCellStyle, TypeConverter, TypeConverter).)
Public method PositionEditingControl Sets the location and size of the editing control hosted by a cell in the DataGridView control. (Inherited from DataGridViewCell.)
Public method PositionEditingPanel Sets the location and size of the editing panel hosted by the cell, and returns the normal bounds of the editing control within the editing panel. (Inherited from DataGridViewCell.)
Protected method RaiseCellClick Raises the DataGridView.CellClick event. (Inherited from DataGridViewElement.)
Protected method RaiseCellContentClick Raises the DataGridView.CellContentClick event. (Inherited from DataGridViewElement.)
Protected method RaiseCellContentDoubleClick Raises the DataGridView.CellContentDoubleClick event. (Inherited from DataGridViewElement.)
Protected method RaiseCellValueChanged Raises the DataGridView.CellValueChanged event. (Inherited from DataGridViewElement.)
Protected method RaiseDataError Raises the DataGridView.DataError event. (Inherited from DataGridViewElement.)
Protected method RaiseMouseWheel Raises the Control.MouseWheel event. (Inherited from DataGridViewElement.)
Protected method SetValue Sets the value of the cell. (Inherited from DataGridViewCell.)
Public method ToString Returns a string that describes the current object. (Overrides DataGridViewCell.ToString().)
Top

The DataGridViewComboBoxCell class is a specialized type of DataGridViewCell used to display a combo box control, which is an editing field combined with a list selection field. The currently selected DataGridViewComboBoxCell hosts a DataGridViewComboBoxEditingControl in which the user can change the cell's value, assuming the cell's ReadOnly property is set to false.

Unlike the ComboBox control, the DataGridViewComboBoxCell does not have SelectedIndex and SelectedValue properties. Instead, selecting a value from a drop-down list sets the cell Value property.

The DataGridViewComboBoxColumn is the column type specialized to hold cells of this type. By default, the DataGridViewComboBoxColumn.CellTemplate is initialized to a new DataGridViewComboBoxCell. To pattern the cells within a column after an existing DataGridViewComboBoxCell, set the column's CellTemplate property to the cell to use as a pattern.

The cell-related properties of the column are wrappers for the similarly-named properties of the template cell. Changing the property values of the template cell will affect only cells based on the template that are added after the change. Changing the cell-related property values of the column, however, will update the template cell and all other cells in the column, and refresh the column display if necessary.

You will typically work with the DataGridViewComboBoxColumn type unless you want to override column values for specific cells. The guidelines described in the DataGridViewComboBoxColumn class overview topic for populating the drop-down list applies to both cell and column instances.

Notes to Inheritors

When you derive from DataGridViewComboBoxCell and add new properties to the derived class, be sure to override the Clone method to copy the new properties during cloning operations. You should also call the base class's Clone method so that the properties of the base class are copied to the new cell.

The following code example demonstrates the DataGridViewComboBoxColumn class, which makes use of the DataGridViewComboBoxCell class. You can set the cell DataSource, ValueMember, and DisplayMember properties in the same way that the corresponding column properties are set in this example. This example is part of a larger example available in the DataGridViewComboBoxColumn class overview topic.


private DataGridViewComboBoxColumn CreateComboBoxColumn()
{
    DataGridViewComboBoxColumn column =
        new DataGridViewComboBoxColumn();
    {
        column.DataPropertyName = ColumnName.TitleOfCourtesy.ToString();
        column.HeaderText = ColumnName.TitleOfCourtesy.ToString();
        column.DropDownWidth = 160;
        column.Width = 90;
        column.MaxDropDownItems = 3;
        column.FlatStyle = FlatStyle.Flat;
    }
    return column;
}

private void SetAlternateChoicesUsingDataSource(DataGridViewComboBoxColumn comboboxColumn)
{
    {
        comboboxColumn.DataSource = RetrieveAlternativeTitles();
        comboboxColumn.ValueMember = ColumnName.TitleOfCourtesy.ToString();
        comboboxColumn.DisplayMember = comboboxColumn.ValueMember;
    }
}

private DataTable RetrieveAlternativeTitles()
{
    return Populate("SELECT distinct TitleOfCourtesy FROM Employees");
}

string connectionString =
    "Integrated Security=SSPI;Persist Security Info=False;" +
    "Initial Catalog=Northwind;Data Source=localhost";

private DataTable Populate(string sqlCommand)
{
    SqlConnection northwindConnection = new SqlConnection(connectionString);
    northwindConnection.Open();

    SqlCommand command = new SqlCommand(sqlCommand, northwindConnection);
    SqlDataAdapter adapter = new SqlDataAdapter();
    adapter.SelectCommand = command;

    DataTable table = new DataTable();
    table.Locale = System.Globalization.CultureInfo.InvariantCulture;
    adapter.Fill(table);

    return table;
}

// Using an enum provides some abstraction between column index
// and column name along with compile time checking, and gives
// a handy place to store the column names.
enum ColumnName
{
    EmployeeId,
    LastName,
    FirstName,
    Title,
    TitleOfCourtesy,
    BirthDate,
    HireDate,
    Address,
    City,
    Region,
    PostalCode,
    Country,
    HomePhone,
    Extension,
    Photo,
    Notes,
    ReportsTo,
    PhotoPath,
    OutOfOffice
};


.NET Framework

Supported in: 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
How to create an editable DataGridViewComboBoxCell

Another issue I've encountered for my project is the need to have an editable DataGridViewComboBoxCell.  Almost all of the documentation I've found implied it couldn't be done.  I did find some documentation that said the job would be difficult.  What follows is my implementation.

Some caveats (there's always something):  I only needed the ability to add one item.  While I will put advice on how to do more than one, please realize that I haven't tried it, and I could be wrong.  Secondly, my data was not linked to a database table, but rather an object in memory.  This means my example will not account for the elephant-level subtleties of database reads and writes.  Finally, the code presented is in VB, although it can be easily transferred into VC#.

Everything followed the previous example, up until the handler for the DataGridView.RowsAdded handler.  In this handler, I now found the need to use a BindingSource object.

Private Sub CreateLink(sender As System.Object, _
            e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) _
        Handles tbl.RowsAdded
    Dim sentIt As DataGridView = TryCast(sender, DataGridView)
    If Not (sentIt Is tblTop) Then
        Exit Sub
    End If

    Dim comboIt As DataGridViewComboBoxCell
    Dim bindIt As BindingSource

    For nRowsAdd As Integer = 0 To e.RowCount - 1
        If (e.RowIndex + nRowsAdd) >= m_listAllDates.Count Then
            m_listAllDates.Add(New SomeDateList())
        End If
        comboIt = CType(sentIt.Rows(e.RowIndex + nRowsAdd).Cells( _
            ENUM_COLS.RATE_COLUMN), DataGridViewComboBoxCell)
        bindIt = New BindingSource()
        bindIt.DataSource = m_listAllDates(e.RowIndex + nRowsAdd).listRate
        comboIt.DataSource = bindIt
    Next
End Sub

The BindingSource object allows for several new events to be thrown, but you are about to see them as unnecessary.  Also, note that the object m_listAllDates has a listRate field that I added, which is the same as the listDate field from the previous example (a List(Of String) object).  This list was initialized with 4 values: 3 constants that must appear each time the DataGridViewComboBoxCell is created (on every single row), and a fourth value, which is my "edit" value.  The edit value appears in the listRate object node zero (i.e. listRate(0) or listRate.Items(0)).

Next is to handle when the cell is edited.  To do so, you need to handle the DataGridView.EditingControlShowing event.  You will find the recommendation about creating an enumeration for your DataGridView columns to be helpful.

Private Sub PackageCurrentControl(sender As System.Object, _
            e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
        Handles tblIt.EditingControlShowing
    Dim tblIt As DataGridView = CType(sender, DataGridView)
    Dim comboIt As ComboBox
    Dim textIt As TextBox
    Dim listMiniAmort As List(Of MiniAmortItem) = _
        m_listAllPayDates(tblIt.CurrentCell.RowIndex).listMiniAmort
    If tblIt Is tblPackage Then
        Select Case CType(tblIt.CurrentCell.ColumnIndex, TABLE_PKG_COLS)
            Case ENUM_COLS.RATE_COLUMN
                comboIt = CType(e.Control, ComboBox)


                RemoveHandler comboIt.KeyDown, AddressOf Me.HandleRateCell
                AddHandler comboIt.KeyDown, AddressOf Me.HandleRateCell
                RemoveHandler comboIt.KeyPress, AddressOf Me.IgnoreKeyPress
                AddHandler comboIt.KeyPress, AddressOf Me.IgnoreKeyPress
                RemoveHandler comboIt.KeyUp, AddressOf Me.IgnoreKeyUp
                AddHandler comboIt.KeyUp, AddressOf Me.IgnoreKeyUp
            Case Else
                textIt = TryCast(e.Control, TextBox)
                If Not (textIt Is Nothing) Then
                    RemoveHandler textIt.KeyDown, AddressOf Me.HandleDateCell
                    RemoveHandler textIt.KeyPress, AddressOf Me.IgnoreKeyPress
                    RemoveHandler textIt.KeyUp, AddressOf Me.IgnoreKeyUp
                Else
                    comboIt = TryCast(e.Control, ComboBox)
                    If Not (comboIt Is Nothing) Then
                        RemoveHandler comboIt.KeyDown, AddressOf Me.HandleRateCell
                        RemoveHandler comboIt.KeyPress, AddressOf Me.IgnoreKeyPress
                        RemoveHandler comboIt.KeyUp, AddressOf Me.IgnoreKeyUp
                    End If
                End If
        End Select
    End If
End Sub

It is important to only handle the columns that you absolutely need to have edit control in this handler, and that you remove the handlers once you enter a column that isn't handled.  I've found that if you do not remove the handlers, they will "bleed" over into unintended columns of your DataGridView.  Another thing to note about the code above is the "Ignore..." methods.  Each of these methods are only one line: e.Handled = True.  I have found, when utilizing the EditingControlShowing event, that if you do not block the other two Key events, you will get your functionality AND the default functionality.  Of course, you should use the event that best describes when you want your changes to fire, but make certain to block the other two.  Also, when using implementing EditingControlShowing, you will need to remove ALL handlers for the events you follow every time.  It's acceptable to use RemoveHandler, even if that handler isn't attached, as no exception is thrown in this case.  It is necessary, however, as adding the same handler twice occassionally does throw an exception.  Also note in VC#, the notation for adding and removing an event handler uses the += and -= operators.

The handler we need to continue with the editable DataGridViewComboBoxCell are the HandleRateCell

Private Sub HandleRateCell(sender As Object, e As KeyEventArgs)
    Dim ecIt As DataGridViewComboBoxEditingControl = _
        CType(sender, DataGridViewComboBoxEditingControl)
    Dim nRow As Integer = tblTop.CurrentCell.RowIndex
    Dim keyIt As Char = e.KeyCode.ToString().Chars(1)
    Dim nIdx As Integer = ecIt.SelectedIndex

' Do some stuff, and track the value for nIdx in the actual global list.
' In this case, the list is m_AllDates(nRow).listRate(nIdx).
' Since the original binding source took from your global object,
' you likely won't need to change nIdx

    Dim bindIt As BindingSource
    Dim colLate As DataGridViewComboBoxCell = _
        CType(tblPackage.Rows(nRow).Cells(TABLE_PKG_COLS.Late_Fee), DataGridViewComboBoxCell)

    bindIt = CType(colLate.DataSource, BindingSource)
    bindIt.ResetBindings(False)
    colLate.Value = m_listAllDates(nRow).listRate(nIdx)
    e.Handled = True
End Sub

How you track your data in this handler is based on your needs.  Once your data is completely tracked and stored in the global object, you now need to recall the BindingSource that you created in the DataGridView.RowAdded event handler.  Notice that you do NOT use the DataGridViewComboEditingControl object that was sent to this method, but rather the actual DataGridViewComboBoxCell that will be the final result.  The two lines before e.Handled=true are the calls that will allow your DataGridViewComboBoxCell to look at the DataSource for the values of the cell, and then set the visible value of the cell to the indexed item on your background object.

For myself, nIdx was always zero for the editing cell.  In the case of needing to add more than one cell, you should maintain a "dummy" cell, either at index 0 or at the end of the list where you will enter new items.  In the case of a dummy cell at index zero, you will need to add/insert into your background list at index 1, and insure that you use the corrected index at the end of the handler above.

How to add data to a DataGridViewComboBoxCell dynamically

The example here shows adding to the .DataSource property of the DataGridViewComboBoxCell, using a database query.  The trouble I had, and others may have, is that my data for the combo box isn't in a database, but rather computed on the fly somehow.  For myself, and the example I'm entering here, I needed a list of dates that were generated from a given date that was typed elsewhere in the table (that is, a DataGridView).

First, you need a list object of some type.  I ended up designing a small, private class object that associated the list of dates with another, larger object list that contained the dates I wanted.  The dates could have been used directly, except for some requirements my superiors had that caused me to massage the dates from the larger object.  Here is the object that contains the data for the DataGridViewComboBoxCell.  It is in Visual Basic, but should work for VC# as well.

Class SomeDateList
    Public listDate As List(Of String)
    Public listDateSrc As List(Of DateSrcItem)
    Public Sub New()
        listDate = New List(Of String)()
        listDateSrc = New List(Of DateSrcItem)
    End Sub

        
    ''' <summary>
    ''' populates the date list
    ''' </summary>
    ''' <param name="dateTop">the date that generates the date list</param>
    Public Sub MakeDateList(ByVal dateTop As Date)
        Dim nStop As Integer = listDateSrc.Count - 1
        listDate.Add(ForceTenCharDate(dateTop)) 'create a string in mm/dd/yyyy format
        For nALoop As Integer = 0 To nStop - 1
            listDate.Add(ForceTenCharDate(listDateSrc(nALoop).DatePropVal))
        Next
    End Sub
End Class

Note the "public" nature of the fields.  SomeDateList is a private class, created in the same form as the DataGridView that uses it.  However, it should be noted, based on the documented example above, that I could have used a function or property, making the fields private.  I believe the result would be the same.  While "bad" practice, public fields in this case were for my personal convenience.

Next, I created a global access object for the form that contains the DataGridView of the type of object above, because I want each row in the DataGridView (each of which uses a DataGridViewComboBoxCell) to contain a different list of dates.  The larger list was instantiated in the form's Load event handler.

Private Sub formIt_Load(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Me.Load
    ' Did some stuff (sorry about the formatting)

m_listAllDates = New List(Of SomeDateList)()
    'Did more stuff
End Sub

Finally, (this is the part I couldn't find anywhere) I created a handler on the RowsAdded event for the DataGridView.  This is the location where I bind the DataGridViewComboBoxCell to my dynamic list.  Since my cells may contain a different list for each row, I need to know the row and insure the new object is available.

Private Sub CreateLink(sender As System.Object, _
            e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) _
        Handles tblIt.RowsAdded
    Dim sentIt As DataGridView = TryCast(sender, DataGridView)
    If Not (sentIt Is tblIt) Then
        Exit Sub
    End If
    Dim comboIt As DataGridViewComboBoxCell
    For nRowsAdd As Integer = 0 To e.RowCount - 1
        m_listAllDates.Add(New SomeDateList())
        comboIt = CType(sentIt.Rows(e.RowIndex + nRowsAdd).Cells( _
            ENUM_COLS.DATE_COLUMN), DataGridViewComboBoxCell)
        comboIt.DataSource = m_listAllDates(e.RowIndex + nRowsAdd).listDate
    Next
End Sub

I use the recommendation from the example, and create an enumeration for my table's columns, giving easy access to the columns as needed.  Now, anytime the list of dates changes for some row, the dates automatically appear in the correct DataGridViewComboBoxCell.  I hope this helps.  All the best in all you do while staying true.