I found this code on the web a while ago. Haven't used it in a while, but it works very well.
Option Strict Off
Option Explicit On
Imports Microsoft.VisualBasic
Imports System
Imports System.Drawing
Imports System.ComponentModel
Imports System.Data
Imports System.Data.Common
'ADD THIS CODE TO A FORM CLASS MODULE, THEN USE IN A DATAGRIDTABLESTYLE AS A COLUMN STYLE
'JUST AS YOU WOULD A DATAGRIDTEXTBOX COLUMN.
'DO LIKE THIS... Dim myComboBoxCol = New DataGridCboBoxColumn
' With myComboBoxCol
' .Width = 100
' .HeaderText = "MyColumnHeader"
' .MappingName = "MyDataGridColumn"
' End With
'Then populate the combo box any way you choose, here is one example
'Dim objDataSource As New classMyData
'Dim r As SqlClient.SqlDataReader = objDataSource.GetMyData
' myComboBoxCol.ColumnComboBox.Items.Clear()
' Do While r.Read
' myComboBoxCol.ColumnComboBox.Items.Add(r.Item("Column1Data"))
'Loop
'myComboBoxCol.ColumnComboBox.DropDownStyle = ComboBoxStyle.DropDownList
'increase the datagridtablestyle height a bit for a better visual
'tablestyle.PreferredRowHeight = (myComboBoxCol.ColumnComboBox.Height + 3)
'HERE IS THE CODE FOR YOUR CLASS
Public Class DataGridCboBoxColumn
Inherits DataGridTextBoxColumn
' use the derived nokeyup combo to avoid tabbing problem
Public WithEvents ColumnComboBox As NoKeyUpCombo
Private WithEvents _source As CurrencyManager
Private _rowNum As Integer
Private _isEditing As Boolean
'Fields
'Constructors
'Events
'Methods
Shared Sub New()
'Warning: Implementation not found
End Sub
Public Sub New()
MyBase.New()
_source = Nothing
_isEditing = False
ColumnComboBox = New NoKeyUpCombo
AddHandler ColumnComboBox.Leave, New EventHandler(AddressOf LeaveComboBox)
AddHandler ColumnComboBox.SelectionChangeCommitted, New EventHandler(AddressOf ComboStartEditing)
End Sub
Protected Overloads Overrides Sub Edit(ByVal source As CurrencyManager, ByVal rowNum As Integer, ByVal bounds As Rectangle, ByVal readOnly1 As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
MyBase.Edit(source, rowNum, bounds, readOnly1, instantText, cellIsVisible)
_rowNum = rowNum
_source = source
ColumnComboBox.Parent = Me.TextBox.Parent
ColumnComboBox.Location = Me.TextBox.Location
ColumnComboBox.Size = New Size(Me.TextBox.Size.Width, ColumnComboBox.Size.Height)
ColumnComboBox.Text = Me.TextBox.Text
Me.TextBox.Visible = False
ColumnComboBox.Visible = True
ColumnComboBox.BringToFront()
ColumnComboBox.Focus()
End Sub
Protected Overloads Overrides Function Commit(ByVal dataSource As CurrencyManager, ByVal rowNum As Integer) As Boolean
If _isEditing Then
_isEditing = False
SetColumnValueAtRow(dataSource, rowNum, ColumnComboBox.Text)
End If
Return True
End Function
Private Sub ComboStartEditing(ByVal sender As Object, ByVal e As EventArgs)
_isEditing = True
MyBase.ColumnStartedEditing(sender)
End Sub
Private Sub LeaveComboBox(ByVal sender As Object, ByVal e As EventArgs)
If _isEditing Then
SetColumnValueAtRow(_source, _rowNum, ColumnComboBox.Text)
_isEditing = False
Invalidate()
End If
ColumnComboBox.Hide()
End Sub
End Class
Public Class NoKeyUpCombo
Inherits ComboBox
Private WM_KEYUP As Integer = &H101
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_KEYUP Then
'ignore keyup to avoid problem with tabbing & dropdownlist;
Return
End If
MyBase.WndProc(m)
End Sub 'WndProc
End Class 'NoKeyUpCombo