?
Solved

Combobox in datagridview cell

Posted on 2006-04-13
11
Medium Priority
?
4,405 Views
Last Modified: 2012-08-14
Hello -

I am tryin to display a combobox in the current cell when clicked. But only in the current cell. All other cells in the column will just have a textbox.

Any help would be fantastic.
0
Comment
Question by:bnye
  • 6
  • 5
11 Comments
 
LVL 14

Accepted Solution

by:
jake072 earned 1000 total points
ID: 16450129
Here's a Class that should help:

Option Strict On
Option Explicit On

Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Data

Public Class DataGridComboBox
    Inherits ComboBox
      Public Sub New()
            MyBase.New()
    End Sub

    Public isInEditOrNavigateMode As Boolean = True
    Private setIndex As Int32
    Private processCLOSEUP As Boolean = True

    Private bForceFound As Boolean = False

    Public Event ChangeIndex(ByVal sender As Object, ByVal e As System.EventArgs)

    Const WM_KEYUP As Int32 = &H101
    Const WM_KEYDOWN As Int32 = &H100
    Const CBN_DROPDOWN As Int32 = &H7
    Const CBN_CLOSEUP As Int32 = &H8
    Const CBN_SELENDOK As Int32 = &H9
    Const CBN_SELCHANGE As Int32 = &H1
    Const WM_COMMAND As Int32 = &H111
    Const WM_USER As Int32 = &H400
    Const OCM__BASE As Int32 = WM_USER + &H1C00
    Const OCM_COMMAND As Int32 = OCM__BASE + WM_COMMAND

    Sub New(ByVal bForceFound As Boolean)
        Me.bForceFound = bForceFound
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

        Select Case m.Msg
            Case OCM_COMMAND
                Dim mIntPtr As Int32 = m.WParam.ToInt32
                'Get notification of combobox list dropdown
                'and enable setting index on list
                'closeup
                If (mIntPtr >> 16) = CBN_DROPDOWN Then
                    processCLOSEUP = True
                End If
                'If user selects an item in the list portion while dropped down
                'disable setting index on closeup
                If (mIntPtr >> 16) = CBN_SELENDOK Then
                    processCLOSEUP = False
                End If
                'If list portion is closing and user
                'has not made a specific selection in
                'the list area, set index
                If processCLOSEUP Then
                    If (mIntPtr >> 16) = CBN_CLOSEUP Then
                        If Me.Items.Count > 0 Then
                            Me.SelectedIndex = setIndex
                        End If
                    End If
                End If
        End Select
        MyBase.WndProc(m)

    End Sub

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean

        Select Case msg.WParam.ToInt32()
            Case CInt(Keys.Up)
                If MyBase.Items.Count > 0 And MyBase.SelectedIndex > 0 Then
                    If MyBase.DroppedDown = False Then
                        MyBase.DroppedDown = True
                    End If
                    MyBase.SelectedIndex -= 1
                    setIndex = MyBase.SelectedIndex
                End If
                Return True

            Case CInt(Keys.Down)
                If MyBase.Items.Count > 0 And MyBase.SelectedIndex < MyBase.Items.Count - 1 Then
                    If MyBase.DroppedDown = False Then
                        MyBase.DroppedDown = True
                        processCLOSEUP = True
                    End If
                    MyBase.SelectedIndex += 1
                    setIndex = MyBase.SelectedIndex
                End If
                Return True

            Case CInt(Keys.Right)
                Return True

            Case CInt(Keys.Left)
                Return False

        End Select
        Return MyBase.ProcessCmdKey(msg, keyData)

    End Function 'ProcessCmdKey

    Protected Overrides Function ProcessKeymessage(ByRef m As System.Windows.Forms.Message) As Boolean
        'Handles the tab key skipping over columns
        If m.Msg = WM_KEYUP Then
            If m.WParam.ToInt32 = CInt(Keys.Tab) Then
                Return True
            ElseIf m.WParam.ToInt32 = CInt(Keys.Up) Or m.WParam.ToInt32 = CInt(Keys.Down) Then
                'Combo_KeyDown(New Object, New KeyEventArgs(CType(m.WParam.ToInt32, Keys)))
                Return True
            Else
                Return MyBase.ProcessKeyMessage(m)
            End If
        Else
            Return MyBase.ProcessKeyMessage(m)
        End If
    End Function

    Private Sub Combo_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp

        ' Do nothing for certain keys such as navigation keys
        With e
            If ((e.KeyCode = Keys.Back) Or _
             (.KeyCode = Keys.Enter) Or _
             (.KeyCode = Keys.Left) Or _
             (.KeyCode = Keys.Right) Or _
             (.KeyCode = Keys.Up) Or _
             (.KeyCode = Keys.Delete) Or _
             (.KeyCode = Keys.Down) Or _
             (.KeyCode = Keys.PageUp) Or _
             (.KeyCode = Keys.PageDown) Or _
             (.KeyCode = Keys.Home) Or _
             (.KeyCode = Keys.ShiftKey) Or _
             (.KeyCode = Keys.End) Or _
             (.KeyCode = Keys.Tab AndAlso .KeyCode = Keys.Shift)) Then

                Return
            End If
        End With

        ' Store the actual text that has been typed
        Dim TypedText As String = Text

        Dim index As Integer = FindString(TypedText)
        ' Get the text of the first match
        If index > -1 Then

            Dim foundText As String = Me.GetItemText(Items(index))

            Dim sAppendText As String = foundText.Substring(TypedText.Length)
            Text = TypedText & sAppendText

            ' Select the portion of the text that was automatically
            ' added so further typing will replace it
            SelectionStart = TypedText.Length
            SelectionLength = sAppendText.Length
            SelectedIndex = index
            'For setting the the index using
            'CBN_CLOSEUP notification (no user selection
            'in dropped down list portion
            If processCLOSEUP Then
                Me.setIndex = index
            End If

        Else
            'Enforces not in list
            If bForceFound = True Then
                ResetText()
            End If
        End If

    End Sub

    Private Sub Combo_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.SelectionChangeCommitted
        RaiseEvent ChangeIndex(sender, e)
    End Sub

    'Private Sub Combo_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
    '    If Me.Items.Count > 0 Then
    '        Select Case e.KeyCode
    '            Case Keys.Down
    '                If Me.SelectedIndex < Me.Items.Count - 1 Then
    '                    Me.SelectedIndex += 1
    '                Else
    '                    Me.SelectedIndex = 0
    '                End If
    '            Case Keys.Up
    '                If Me.SelectedIndex > 0 Then
    '                    Me.SelectedIndex -= 1
    '                Else
    '                    Me.SelectedIndex = Me.Items.Count - 1
    '                End If
    '        End Select
    '    End If
    'End Sub

End Class


Public Class DataGridComboBoxColumnStyle

    Inherits DataGridColumnStyle
    '
    ' UI constants    
    '
    Private xMargin As Integer = 2
    Private yMargin As Integer = 0
    '
    '
    Public WithEvents Combo As DataGridComboBox
    Private m_DisplayMember, m_ValueMember As String
    Private WithEvents cm As CurrencyManager
    Private dV As New DataView
    Private mDropDown As Boolean
    '
    ' Used to track editing state
    '
    Private OldVal As String = String.Empty
    Private InEdit As Boolean = False

    Private bForceFound As Boolean
    Private bAllowNew As Boolean

    Public Event CreateNew(ByVal strText As String)
    Public Event SelectedValue_Changed(ByVal sender As Object, ByVal e As EventArgs)
    Public Event Leave()

#Region " New "

    Public Sub New()
    End Sub

    ' DATATABLE
    ' Create a new column - DisplayMember, ValueMember
    ' Passed by ordinal
    '
    Public Sub New(ByVal DataSource As DataTable, ByVal DisplayMember As Integer, ByVal ValueMember As Integer, ByVal _DropDownWidth As Integer, Optional ByVal bAllowNew As Boolean = True, Optional ByVal DropDownOnEdit As Boolean = True, Optional ByVal ForceFind As Boolean = False)

        Me.bForceFound = ForceFind
        Me.Combo = New DataGridComboBox(bForceFound)
        Me.bAllowNew = bAllowNew

        InEdit = False

        Me.m_DisplayMember = DataSource.Columns.Item(index:=DisplayMember).ToString
        Me.m_ValueMember = DataSource.Columns.Item(index:=ValueMember).ToString

        With Me.Combo
            .Visible = False
            .DataSource = DataSource
            .DisplayMember = m_DisplayMember
            .ValueMember = m_ValueMember
            .DropDownStyle = ComboBoxStyle.DropDown
            .DropDownWidth = _DropDownWidth
            .MaxDropDownItems = 20
            mDropDown = DropDownOnEdit
            AddHandler .Enter, AddressOf Me.DataGridComboBox_Enter
            AddHandler .Leave, AddressOf DataGridComboBox_Leave
            AddHandler .KeyPress, AddressOf DataGridComboBox_KeyPress
        End With

        Me.dV = DataSource.DefaultView

    End Sub
    ' DATATABLE
    ' Create a new column - DisplayMember, ValueMember
    ' passed by string
    '
    Public Sub New(ByVal DataSource As DataTable, ByVal DisplayMember As String, ByVal ValueMember As String, ByVal _DropDownWidth As Integer, Optional ByVal bAllowNew As Boolean = True, Optional ByVal DropDownOnEdit As Boolean = True, Optional ByVal ForceFind As Boolean = False)

        Me.bForceFound = ForceFind
        Me.Combo = New DataGridComboBox(bForceFound)
        Me.bAllowNew = bAllowNew

        InEdit = False

        With Me.Combo
            .Visible = False
            .DataSource = DataSource
            .DisplayMember = DisplayMember
            .ValueMember = ValueMember
            .DropDownStyle = ComboBoxStyle.DropDown
            .DropDownWidth = _DropDownWidth
            .MaxDropDownItems = 20
            mDropDown = DropDownOnEdit
            AddHandler .Enter, AddressOf Me.DataGridComboBox_Enter
            AddHandler .Leave, AddressOf DataGridComboBox_Leave
            AddHandler .KeyPress, AddressOf DataGridComboBox_KeyPress
        End With

        Me.dV = DataSource.DefaultView

    End Sub
    ' DATVIEW
    ' Create a new column - DisplayMember, ValueMember
    ' Passed by ordinal
    '
    Public Sub New(ByVal DataSource As DataView, ByVal DisplayMember As Integer, ByVal ValueMember As Integer, ByVal _DropDownWidth As Integer, Optional ByVal bAllowNew As Boolean = True, Optional ByVal DropDownOnEdit As Boolean = True, Optional ByVal ForceFind As Boolean = False)

        Me.bForceFound = ForceFind
        Me.Combo = New DataGridComboBox(bForceFound)
        Me.bAllowNew = bAllowNew

        InEdit = False

        Me.m_DisplayMember = DataSource.Table.Columns.Item(index:=DisplayMember).ToString
        Me.m_ValueMember = DataSource.Table.Columns.Item(index:=ValueMember).ToString

        With Me.Combo
            .Visible = False
            .DataSource = DataSource
            .DisplayMember = m_DisplayMember
            .ValueMember = m_ValueMember
            .DropDownStyle = ComboBoxStyle.DropDown
            .DropDownWidth = _DropDownWidth
            .MaxDropDownItems = 20
            mDropDown = DropDownOnEdit
            AddHandler .Enter, AddressOf Me.DataGridComboBox_Enter
            AddHandler .Leave, AddressOf DataGridComboBox_Leave
            AddHandler .KeyPress, AddressOf DataGridComboBox_KeyPress
        End With

        Me.dV = DataSource

    End Sub
    ' DATAVIEW
    ' Create a new column - DisplayMember, ValueMember
    ' passed by string
    '
    Public Sub New(ByVal DataSource As DataView, ByVal DisplayMember As String, ByVal ValueMember As String, ByVal _DropDownWidth As Integer, Optional ByVal bAllowNew As Boolean = True, Optional ByVal DropDownOnEdit As Boolean = True, Optional ByVal ForceFind As Boolean = False)

        Me.bForceFound = ForceFind
        Me.Combo = New DataGridComboBox(bForceFound)
        Me.bAllowNew = bAllowNew

        InEdit = False

        With Me.Combo
            .Visible = False
            .DataSource = DataSource
            .DisplayMember = DisplayMember
            .ValueMember = ValueMember
            .DropDownStyle = ComboBoxStyle.DropDown
            .DropDownWidth = _DropDownWidth
            .MaxDropDownItems = 20
            mDropDown = DropDownOnEdit
            AddHandler .Enter, AddressOf Me.DataGridComboBox_Enter
            AddHandler .Leave, AddressOf DataGridComboBox_Leave
            AddHandler .KeyPress, AddressOf DataGridComboBox_KeyPress
        End With

        Me.dV = DataSource

    End Sub

#End Region

    '
    '------------------------------------------------------
    ' Methods overridden from DataGridColumnStyle
    '------------------------------------------------------
    '
    ' Abort Changes
    '
    Protected Overloads Overrides Sub Abort(ByVal RowNum As Integer)

        RollBack()
        HideComboBox()
        EndEdit()
    End Sub
    '
    ' Commit Changes
    '
    Protected Overloads Overrides Function Commit(ByVal DataSource As CurrencyManager, ByVal RowNum As Integer) As Boolean
        If bForceFound = False And bAllowNew = True Then
            Dim strFoundText As String = Me.Combo.Text
            If Me.Combo.FindStringExact(strFoundText) = -1 And strFoundText.Length > 0 Then
                If MessageBox.Show("Cannot find Item: '" & strFoundText & "'" & vbCrLf & "Would you like to create a new Item ?", "Create New", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then
                    RaiseEvent CreateNew(strFoundText)
                    InEdit = True
                End If
            End If
        End If

        HideComboBox()

        If Not InEdit Then
            Return True
        End If

        InEdit = False

        Try

            Dim Value As Object = Me.Combo.SelectedValue
            If NullText.Equals(Value) Then
                Value = Convert.DBNull
            End If
            SetColumnValueAtRow(DataSource, RowNum, Me.Combo.SelectedValue)

        Catch ex As Exception
            Debug.WriteLine(ex.ToString)
            RollBack()
            Return False
        End Try

        EndEdit()

        Return True

    End Function
    '
    ' Try to Handle SelectionChangeCommitted...
    '
    Protected Sub SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Combo.ChangeIndex
        ' If the parent of the datagrid is a form...
        If TypeOf (MyBase.DataGridTableStyle.DataGrid.Parent) Is Form Then
            ' Get a reference to the form, to get the currencymanager.
            Dim frm As Form = CType(MyBase.DataGridTableStyle.DataGrid.Parent, Form)
            ' Get the currency manager associated with the form.
            Dim cm As CurrencyManager = CType(frm.BindingContext(MyBase.DataGridTableStyle.DataGrid.DataSource, MyBase.DataGridTableStyle.DataGrid.DataMember), CurrencyManager)

            ' Try and set the value.
            Try
                SetColumnValueAtRow(cm, MyBase.DataGridTableStyle.DataGrid.CurrentRowIndex, Me.Combo.SelectedValue)
            Catch ex As Exception
                Debug.WriteLine(ex.Message)
            End Try
        End If
    End Sub
    '
    ' Edit Grid
    '
    Protected Overloads Overrides Sub Edit(ByVal Source As CurrencyManager, ByVal Rownum As Integer, ByVal Bounds As Rectangle, ByVal [ReadOnly] As Boolean, ByVal InstantText As String, ByVal CellIsVisible As Boolean)

        Try

            With Me.Combo

                '.Text = String.Empty

                Dim OriginalBounds As Rectangle = Bounds

                OldVal = .Text

                If CellIsVisible Then
                    Bounds.Offset(xMargin, yMargin)
                    Bounds.Width -= xMargin * 2
                    Bounds.Height -= yMargin
                    .Bounds = Bounds
                    .Visible = True

                Else
                    .Bounds = OriginalBounds
                    .Visible = False
                End If

                If .FindStringExact(.Text) > -1 Then
                    .SelectedValue = GetColumnValueAtRow(Source, Rownum)
                Else
                    .SelectedIndex = -1
                End If

                If Not InstantText Is Nothing Then
                    .SelectedValue = InstantText
                Else
                    .Select(.Text.Length, 0)
                End If

                .RightToLeft = Me.DataGridTableStyle.DataGrid.RightToLeft
                .Focus()

                If .Visible Then
                    Me.DataGridTableStyle.DataGrid.Invalidate(OriginalBounds)
                End If

            End With

            InEdit = True

        Catch ex As Exception
            Debug.WriteLine(ex.ToString)
            InEdit = False
            RollBack()

        End Try

    End Sub

    Protected Overloads Overrides Function GetMinimumHeight() As Integer
        Return Me.Combo.PreferredHeight + yMargin
    End Function

    Protected Overloads Overrides Function GetPreferredHeight(ByVal g As Graphics, _
     ByVal Value As Object) As Integer
        Dim NewLineIndex As Integer = 0
        Dim NewLines As Integer = 0
        Dim ValueString As String = Me.GetTxt(Value)
        Do
            While NewLineIndex <> -1
                NewLineIndex = ValueString.IndexOf("r\n", NewLineIndex + 1)
                NewLines += 1
            End While
        Loop

        Return FontHeight * NewLines + yMargin
    End Function

    Protected Overloads Overrides Function GetPreferredSize(ByVal g As Graphics, _
      ByVal Value As Object) As Size
        Dim Extents As Size = Size.Ceiling(g.MeasureString(GetTxt(Value), _
          Me.DataGridTableStyle.DataGrid.Font))
        Extents.Width += xMargin * 2 + DataGridTableGridLineWidth
        Extents.Height += yMargin
        Return Extents
    End Function

    Protected Overloads Overrides Sub Paint(ByVal g As Graphics, _
     ByVal Bounds As Rectangle, _
     ByVal Source As CurrencyManager, _
     ByVal RowNum As Integer)

        Paint(g, Bounds, Source, RowNum, False)
    End Sub

    Protected Overloads Overrides Sub Paint(ByVal g As Graphics, _
     ByVal Bounds As Rectangle, _
     ByVal Source As CurrencyManager, _
     ByVal RowNum As Integer, _
     ByVal AlignToRight As Boolean)

        Dim Text As String = GetTxt(GetColumnValueAtRow(Source, RowNum))
        PaintText(g, Bounds, Text, RowNum, AlignToRight)
    End Sub

    Protected Overloads Sub Paint(ByVal g As Graphics, _
       ByVal Bounds As Rectangle, _
       ByVal Source As CurrencyManager, _
       ByVal RowNum As Integer, _
       ByVal BackBrush As Brush, _
       ByVal ForeBrush As Brush, _
       ByVal AlignToRight As Boolean)

        Dim Text As String = GetTxt(GetColumnValueAtRow(Source, RowNum))
        PaintText(g, Bounds, Text, BackBrush, ForeBrush, RowNum, AlignToRight)
    End Sub

    Protected Overloads Overrides Sub SetDataGridInColumn(ByVal Value As DataGrid)
        MyBase.SetDataGridInColumn(Value)
        If Not (Me.Combo.Parent Is Value) Then
            If Not (Me.Combo.Parent Is Nothing) Then
                Me.Combo.Parent.Controls.Remove(Me.Combo)
            End If
        End If

        If Not (Value Is Nothing) Then Value.Controls.Add(Me.Combo)
    End Sub

    Protected Overloads Overrides Sub UpdateUI(ByVal Source As CurrencyManager, _
     ByVal RowNum As Integer, ByVal InstantText As String)

        If Not (InstantText Is Nothing) Then
            Me.Combo.Text = InstantText
        End If
    End Sub

    '----------------------------------------------------------------------
    ' Helper Methods
    '----------------------------------------------------------------------

    Private ReadOnly Property DataGridTableGridLineWidth() As Integer
        Get
            If DataGridTableStyle.GridLineStyle = DataGridLineStyle.Solid Then
                Return 1
            Else
                Return 0
            End If
        End Get

    End Property

    Public Sub SetDataSource(ByVal dt As DataTable)
        Me.Combo.DataSource = dt
    End Sub


    Private Sub EndEdit()
        InEdit = False
        Invalidate()
    End Sub

    Private Function GetTxt(ByVal s As Object) As String

        Try

            If s Is DBNull.Value Then Return NullText
            If Not s Is Nothing Then
                'Set up the delimiters for the search string based on TypeOf s
                Dim strFilter As String = String.Empty

                If TypeOf (Me.Combo.ValueMember) Is String Then
                    strFilter = "'" & s.ToString & "'"
                ElseIf TypeOf (Me.Combo.ValueMember) Is DateTime Then
                    strFilter = "#" & s.ToString & "#"
                Else
                    strFilter = s.ToString
                End If

                'Use datatable.select method

                Dim drarr() As DataRow = Me.dV.Table.Select(Me.Combo.ValueMember & " = " & strFilter)

                If drarr.Length > 0 Then      'Value found
                    'Return associated Display Member
                    Return drarr(0)(Me.Combo.DisplayMember).ToString
                Else      'Value NOT found
                    Return String.Empty
                End If
            Else
                Return String.Empty
            End If

        Catch ex As Exception
            Console.WriteLine(ex.ToString)
        End Try

    End Function


    Private Sub HideComboBox()

        If Me.Combo.Focused Then
            Me.DataGridTableStyle.DataGrid.Focus()
        End If
        Me.Combo.Visible = False

    End Sub

    Private Sub RollBack()
        Me.Combo.Text = OldVal
    End Sub

    Private Sub PaintText(ByVal g As Graphics, ByVal Bounds As Rectangle, ByVal Text As String, ByVal RowNum As Integer, _
        ByVal AlignToRight As Boolean)

        Dim BackBrush As Brush
        Dim ForeBrush As Brush = New SolidBrush(DataGridTableStyle.ForeColor)
        If Me.DataGridTableStyle.DataGrid.IsSelected(RowNum) Then
            BackBrush = New SolidBrush(DataGridTableStyle.SelectionBackColor)
        Else
            BackBrush = New SolidBrush(DataGridTableStyle.BackColor)
        End If
        PaintText(g, Bounds, Text, BackBrush, ForeBrush, RowNum, AlignToRight)

    End Sub

    Private Sub PaintText(ByVal g As Graphics, ByVal TextBounds As Rectangle, ByVal Text As String, ByVal BackBrush As Brush, _
        ByVal ForeBrush As Brush, ByVal RowNum As Integer, ByVal AlignToRight As Boolean)

        Dim Rect As Rectangle = TextBounds
        Dim RectF As RectangleF = RectF.op_Implicit(Rect)    ' Convert to RectangleF
        Dim Format As StringFormat = New StringFormat

        If AlignToRight Then
            Format.FormatFlags = StringFormatFlags.DirectionRightToLeft
        End If

        Select Case Me.Alignment
            Case HorizontalAlignment.Left
                Format.Alignment = StringAlignment.Near
            Case HorizontalAlignment.Right
                Format.Alignment = StringAlignment.Far
            Case HorizontalAlignment.Center
                Format.Alignment = StringAlignment.Center
        End Select

        Format.FormatFlags = Format.FormatFlags Or StringFormatFlags.NoWrap
        g.FillRectangle(Brush:=BackBrush, Rect:=Rect)

        Rect.Offset(0, yMargin)
        Rect.Height -= yMargin
        g.DrawString(Text, Me.DataGridTableStyle.DataGrid.Font, ForeBrush, RectF, Format)
        Format.Dispose()

    End Sub

    Private Sub DataGridComboBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim dG As DataGrid = Me.DataGridTableStyle.DataGrid

        Me.cm = CType(dG.BindingContext(dG.DataSource, dG.DataMember), CurrencyManager)

        'Prevent combo from setting to list position 0 on enter
        If MyBase.GetColumnValueAtRow(cm, cm.Position) Is DBNull.Value Then
            Me.Combo.SelectedIndex = -1
        End If

    End Sub

    Private Sub DataGridComboBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs)

        If InEdit Then
            If Me.Combo.SelectedIndex > -1 And cm.Position > -1 Then
                SetColumnValueAtRow(cm, cm.Position, Me.Combo.SelectedValue)
            End If
            EndEdit()
        End If

        HideComboBox()
        RaiseEvent Leave()
    End Sub

    Public Sub SetValue(ByVal value As Object)
        If InEdit Then
            If Me.Combo.SelectedIndex > -1 And cm.Position > -1 Then
                SetColumnValueAtRow(cm, cm.Position, Me.Combo.SelectedValue)
            End If
            EndEdit()
        Else
            SetColumnValueAtRow(cm, cm.Position, value)
        End If

        Me.Combo.SelectedValue = value

        HideComboBox()
        RaiseEvent Leave()
    End Sub

    Private Sub DataGridComboBox_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)

        If Char.IsLetterOrDigit(e.KeyChar) Then
            InEdit = True
            MyBase.ColumnStartedEditing(Me.Combo)
            'Handle the optional autoDropDownOnEdit setting
            If mDropDown Then
                If Not Me.Combo.DroppedDown Then
                    Me.Combo.DroppedDown = True
                End If
            End If
        End If

    End Sub

    Private Sub Combo_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Combo.SelectedIndexChanged
        InEdit = True
        MyBase.ColumnStartedEditing(Me.Combo)
    End Sub

    Private Sub Combo_DataSourceChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Combo.DataSourceChanged
        If TypeOf (Me.Combo.DataSource) Is DataTable Then
            Me.dV = CType(Me.Combo.DataSource, DataTable).DefaultView
        ElseIf TypeOf (Me.Combo.DataSource) Is DataView Then
            Me.dV = CType(Me.Combo.DataSource, DataView)
        Else
            Dim i As Integer = -1
        End If

    End Sub

    Private Sub Combo_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Combo.SelectedValueChanged
        RaiseEvent SelectedValue_Changed(sender, e)
    End Sub
End Class

Usage Example:

        colBlank = New DataGridComboBoxColumnStyle(dvBlank, "extPartName", "id", 120) ' dvBlank is a DataView, DisplayMember, Value Member, DropDownWidth of Combo in column.
        With colBlank
            .MappingName = "blankID"
            .HeaderText = "Blank Item"
            .Width = 120
            .NullText = "Choose one..."
        End With
        tsB.GridColumnStyles.Add(colBlank)

Note: this column also has autocompletion if the user is typing in data, and the combobox is shown when the column has focus.

Hope it helps!

Jake
0
 

Author Comment

by:bnye
ID: 16457554
Hey thanks for the response. You will have to give me a bit to test this guy out. Thats a lot to take in.

Thanks again. I will have your points for you shortly.

Sincerely,

Ben
0
 

Author Comment

by:bnye
ID: 16458464
Jake -

I had a couple of questions. Please excuse my ignorance.

I used this as shown and didn't add the column. I think I am getting close:

        '
        'dgUserMap
        '
        Me.dgUserMap.DataMember = ""
        Me.dgUserMap.HeaderForeColor = System.Drawing.SystemColors.ControlText
        Me.dgUserMap.Location = New System.Drawing.Point(25, 85)
        Me.dgUserMap.Name = "dgUserMap"
        Me.dgUserMap.Size = New System.Drawing.Size(265, 193)
        Me.dgUserMap.TabIndex = 4

        Me.colBlank = New DataGridComboBoxColumnStyle(dvBlank, "extPartName", "id", 120) ' dvBlank is a DataView, DisplayMember, Value Member, DropDownWidth of Combo in column.
        With colBlank
            .MappingName = "blankID"
            .HeaderText = "Blank Item"
            .Width = 120
            .NullText = "Choose one..."
        End With

        tsb.GridColumnStyles.Add(colBlank)

        dgUserMap.TableStyles.Add(tsb)


-----------------------------------------------------------------------------------------

Do you have a new version for datagridview or just this one for datagrid?
Thanks again for all of you help.

Sincerely,

Ben
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:bnye
ID: 16474991
Has anyone seen this for the DataGridView?

Thanks,

Ben
0
 
LVL 14

Expert Comment

by:jake072
ID: 16480024
I do not have this for the DataGridView...

Let me check into this, and I'll see if I can develop a work around for the DataGridView... What version of VS are you running?

Jake
0
 

Author Comment

by:bnye
ID: 16484055
2005

Thanks for you help Jake. I have been trying to work your example in 2005, but sadly I kinda suck at the datagridview.

PS I couldn't get your example to work using the datagrid either. Can you take a looksee at what I did above and see why it didn't run.

Sincerely,

Ben
0
 
LVL 14

Expert Comment

by:jake072
ID: 16506976
You have to make sure that you set the Display, ValueMember and MappingName to the columns in your grid.  

The parameters for the ColumnStyle are: A DataTable/View, the DISPLAY MEMBER for the combo, the VALUE MEMBER for the combo...

Also, in the MappingName of the Combo, this has to be the Foreign Key that links the 2 Tables together.

Make sure that your TableStyle.MappingName is set to the proper table as well...

I'll get to you tomorrow with a DataGridView example, as I am quite busy at the moment.

Let me know if you need more help - If you still can't get the example working in a DataGrid, then could you post the Table Structures that your using, so that I could help you further, then we can make it work in the DataGridView...

Cheers,

Jake
0
 

Author Comment

by:bnye
ID: 16513289
thank Jake -

no rush on the datagridview. I will can't try the datagrid until sunday. I will try and post more sunday evening.

thanks again,

Ben
0
 
LVL 14

Expert Comment

by:jake072
ID: 16548127
Ben,

Sorry for the delay, I've been extremely busy, and haven't had time to work something out for you...

Did you get it to run in a DataGrid?  Note: This code was developed for the 1.1 framework.

Jake

0
 

Author Comment

by:bnye
ID: 16564040
Yeah this week has been crazy. I am awarding you the points. I think I just need to spend some time working it.

Thanks again for your help.

Sincerely,

Ben
0
 
LVL 14

Expert Comment

by:jake072
ID: 16579017
Ben,

Just let me know if you need further help... Also notice that VS 2005 HAS a BUILT IN combobox for a datagridview!

Cheers,

Jake
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
Is your OST file inaccessible, Need to transfer OST file from one computer to another? Want to convert OST file to PST? If the answer to any of the above question is yes, then look no further. With the help of Stellar OST to PST Converter, you can e…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question