About Me

My photo
Northglenn, Colorado, United States
I'm primarily a BI Developer on the Microsoft stack. I do sometimes touch upon other Microsoft stacks ( web development, application development, and sql server development).

Monday, April 30, 2007

VB.Net: An editable combo box

So, I had to make a editable combo box took me longer then I've hoped.

In a custom made datagrid combo box column, which inherits from
DataGridColumnStyle. I have 3 functions that were mainly used in this custom datagrid combo box column. (BTW I also have a custom comboBox control, but nothing in that control that was needed to make this work):


Public Sub New(ByVal colName As String, ByVal dataSource As DataTable, ByVal displayMember As String, ByVal valueMember As String, ByVal dataGrid As DataGrid, ByVal editable As Boolean)

...
_ComboBox = New ctlComboBox
_ComboBox.Visible = True
_hasTextBox = editable

_dv = dataSource.DefaultView
_ComboBox.DataSource = _dv
_dataTable = dataSource
_dataTableAll = dataSource
_ComboBox.DisplayMember = displayMember
_displayMember = displayMember
_ComboBox.ValueMember = valueMember
_valueMember = valueMember

Me.Editable()

Dim _graphicsContext As Graphics = dataGrid.CreateGraphics
Dim _widest As Double = 1
Dim _stringSize As SizeF = New SizeF(0, 0)

Dim dr As DataRow
For Each dr In dataSource.Rows
_stringSize = _graphicsContext.MeasureString(dr(displayMember).ToString, dataGrid.Font)
If (_stringSize.Width > _widest) Then
_widest = _stringSize.Width
End If
Next
_ComboBox.DropDownWidth = CType(Math.Ceiling(_widest), Integer)
Me.Width = _ComboBox.DropDownWidth + 25
Me.MappingName = colName
Me.HeaderText = colName
dataGrid.Controls.Add(_ComboBox)
End Sub

--AND--

Private Sub _comboBox_MouseUp(ByVal sender As Object, ByVal e As System.EventArgs) Handles _ComboBox.SelectionChangeCommitted
If (_hasTextBox) Then
RaiseEvent ComboBox_Edit(Me._ComboBox.Text)
End If
End Sub

--AND--


Public Sub Editable()
Dim dropDownButtonWidth As Integer = 14
If _hasTextBox Then
_ComboBox.DrawMode = DrawMode.Normal
_ComboBox.DropDownStyle() = ComboBoxStyle.DropDown
_ComboBox.Show()
_ComboBox.Visible() = True
_ComboBox.Focus()
HideComboBox()
End If
End Sub


###
Okay, now in my form I have a function that handles the event I throw from the datagrid combo box:
###


Private Sub ComboBox_Edit(ByVal value As String) Handles colName.ComboBox_Edit
Try

Me.dvShifts.Table().Rows(Me.dgrShifts.CurrentRowIndex)("Name") = value 'Set the value selected

If (Me.colName.SelectedIndex > -1 AndAlso _
Not IsDBNull(dsShifts.Tables(1).Rows(Me.colName.SelectedIndex())("ID"))) Then

'Set the datagrid values based on the selected information if need to.

End If

'Make a new column to implement changes if edited
colName = New ctlDataGridComboBoxColumn("Name", dsShifts.Tables(1), "Name", "Name", Me.dgrShifts, True)
colName.MappingName = "Name"
colName.HeaderText = "Name"

Me.colName.SelectedValue() = value
Me.colName.DataSourceTable() = dsShifts.Tables(1)
colName.Width() = ResizeColumn("Name", "Name")
'Some other custom function calls
...

Catch ex As Exception
'adding new row to datagrid
If (Me.colName.SelectedIndex > -1 AndAlso _
Not IsDBNull(dsShifts.Tables(1).Rows(Me.colName.SelectedIndex())("Shift_ID"))) Then

Dim newDR As DataRow
newDR = Me.dsShifts.Tables(0).NewRow()
newDR.Item("Name") = value
... 'other custom stuff
End If

colName = New ctlDataGridComboBoxColumn("Name", dsShifts.Tables(1), "Name", "Name", Me.dgrShifts, True)
colName.MappingName = "Name"
colName.HeaderText = "Name"
Me.colName.SelectedValue() = value
Me.colName.DataSourceTable() = dsShifts.Tables(1)
Me.dgrShifts.Update()
colName.Width() = ResizeColumn("Name", "Name")
BindControl()
End Try
End Sub


That is the bare minimum without going into great detail of how to get an editable combo box in a datagrid column.