I have spent 4 days, yes 4!, searching , reading and not understanding a word about getting a combo box in a datagrid.
I have a class I call it, nothing happens, no errors, just me screaming!
If I show my code could someone tell me whats wrong? Theres a mars bar in it!
‘This is the form it’s called from
[vbcode]
Private Sub LoadRotaGrid()
Me.SuspendLayout()
‘load rotaGrid
Dim oRota As StaffRota = New StaffRota
Dim oDataRota As DataTable = oRota.GetRotaData ‘CoreData
Dim oDataStaff As DataTable = oRota.GetSSStaff ‘ComboData
Dim oTblStyle As New DataGridTableStyle
oTblStyle.MappingName() = “Rota”
‘ComboBox Column
Dim aCol3 As New DataGridComboBoxColumn
With aCol3
.MappingName = “RotaEmployee” ‘coredata field to match
.HeaderText = “Employee”
.Width = 100
.ColumnComboBox.DataSource = oDataStaff
.ColumnComboBox.DisplayMember = “FullName”
.ColumnComboBox.ValueMember = “EmployeeID” ‘//combodata field to match
oTblStyle.PreferredRowHeight = .ColumnComboBox.Height
oTblStyle.GridColumnStyles.Add(aCol3)
End With
With grdRota
.TableStyles.Clear()
.TableStyles.Add(oTblStyle)
.DataSource = oDataRota
End With
Me.ResumeLayout()
End Sub
[/vbcode]
‘Here’s the class
[vbcode]
Imports System
‘
‘ Derive a custom column style from DataGridTextBoxColumn that:
‘ – adds a ComboBox member
‘ – tracks when the combobox has focus in the Enter and Leave events
‘ – overrides Edit event so the ComboBox replaces the TextBox
‘ – overrides Commit event to save the changed data
‘
Public Class DataGridComboBoxColumn
#Region ” Declarations ”
Inherits DataGridTextBoxColumn
Public ColumnComboBox As NoKeyUpCombo
Private mcmSource As System.Windows.Forms.CurrencyManager
Private mintRowNum As Integer
Private mblnEditing As Boolean
#End Region
#Region ” Constructor ”
Public Sub New()
mcmSource = Nothing
mblnEditing = False
ColumnComboBox = New NoKeyUpCombo
ColumnComboBox.DropDownStyle = ComboBoxStyle.DropDownList
AddHandler ColumnComboBox.Leave, AddressOf LeaveComboBox
AddHandler ColumnComboBox.SelectionChangeCommitted, AddressOf ComboStartEditing
End Sub
#End Region
#Region ” Private Methods ”
Private Sub HandleScroll(ByVal sender As Object, ByVal e As EventArgs)
If ColumnComboBox.Visible Then ColumnComboBox.Hide()
End Sub
Private Sub ComboStartEditing(ByVal sender As Object, ByVal e As EventArgs)
mblnEditing = True
MyBase.ColumnStartedEditing(DirectCast(sender, System.Windows.Forms.Control))
End Sub
Private Sub LeaveComboBox(ByVal sender As Object, ByVal e As EventArgs)
If mblnEditing Then
SetColumnValueAtRow(mcmSource, mintRowNum, ColumnComboBox.Text)
mblnEditing = False
Invalidate()
End If
ColumnComboBox.Hide()
AddHandler Me.DataGridTableStyle.DataGrid.Scroll, New EventHandler(AddressOf HandleScroll)
End Sub
#End Region
#Region ” Overridden Methods ”
Protected Overloads Overrides Sub Edit( _
ByVal [source] As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer, _
ByVal bounds As System.Drawing.Rectangle, _
ByVal [readOnly] As Boolean, _
ByVal instantText As String, _
ByVal cellIsVisible As Boolean)
MyBase.Edit([source], rowNum, bounds, [readOnly], instantText, cellIsVisible)
mintRowNum = rowNum
mcmSource = [source]
With ColumnComboBox
.Parent = Me.TextBox.Parent
.Location = Me.TextBox.Location
.Size = New Size(Me.TextBox.Size.Width, .Size.Height)
.SelectedIndex = .FindStringExact(Me.TextBox.Text)
.Text = Me.TextBox.Text
Me.TextBox.Visible = False
.Visible = True
AddHandler Me.DataGridTableStyle.DataGrid.Scroll, AddressOf HandleScroll
.BringToFront()
.Focus()
End With
End Sub
Protected Overrides Function Commit( _
ByVal dataSource As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer) As Boolean
If mblnEditing Then
mblnEditing = False
SetColumnValueAtRow(dataSource, rowNum, ColumnComboBox.Text)
End If
Return True
End Function
Protected Overrides Sub ConcedeFocus()
Console.WriteLine(“ConcedeFocus”)
MyBase.ConcedeFocus()
End Sub
Protected Overrides Function GetColumnValueAtRow( _
ByVal [source] As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer) As Object
Dim s As Object = MyBase.GetColumnValueAtRow([source], rowNum)
Dim dv As DataView = CType(Me.ColumnComboBox.DataSource, DataView)
Dim rowCount As Integer = dv.Count
Dim i As Integer = 0
Dim obj As Object
While i < rowCount
obj = dv(i)(Me.ColumnComboBox.ValueMember)
If (Not obj Is DBNull.Value) AndAlso _
(Not s Is DBNull.Value) AndAlso _
(s Is obj) Then
Exit While
End If
i += 1
End While
If i < rowCount Then
Return dv(i)(Me.ColumnComboBox.DisplayMember)
End If
Return DBNull.Value
End Function
Protected Overrides Sub SetColumnValueAtRow( _
ByVal [source] As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer, ByVal value As Object)
Dim s As Object = value
Dim dv As DataView = CType(Me.ColumnComboBox.DataSource, DataView)
Dim rowCount As Integer = dv.Count
Dim i As Integer = 0
Dim obj As Object
While i < rowCount
obj = dv(i)(Me.ColumnComboBox.DisplayMember)
If (Not obj Is DBNull.Value) AndAlso _
(s Is obj) Then
Exit While
End If
i += 1
End While
If i < rowCount Then
s = dv(i)(Me.ColumnComboBox.ValueMember)
Else
s = DBNull.Value
End If
MyBase.SetColumnValueAtRow([source], rowNum, s)
End Sub
#End Region
Private Sub InitializeComponent()
End Sub
End Class
[/vbcode]
A related class
[vbcode]
Public Class NoKeyUpCombo
Inherits System.Windows.Forms.ComboBox
Private Const WM_KEYUP As Integer = &H101
Protected Overrides Sub WndProc(ByRef theMessage As System.Windows.Forms.Message)
'
' Ignore KeyUp event to avoid problem with tabbing the dropdown.
' Prevent tabbing through cells from leaving focus over the cell
' that contains the combobox.
'
If theMessage.Msg = WM_KEYUP Then
Return
Else
MyBase.WndProc(theMessage)
End If
End Sub
End Class
[/vbcode]