Marco Sánchez Marco Sánchez - 3 months ago 20
Vb.net Question

Visual basic Populate DataGridView with ComboBoxColumn

Let's say I have a DataGridView with a ComboBoxColumn. I add the Items for the ComboBoxes as follows:

Dim colors = New Dictionary(Of String, String)()
colors("10") = "Red"
colors("20") = "Blue"
colors("30") = "Green"
colors("40") = "Yellow"
ComboBox1.DataSource = New BindingSource(colors, Nothing)
ComboBox1.DisplayMember = "Value"
ComboBox1.ValueMember = "Key"


Then when the program strarts the DataGridView must be populated from a DataBase and the ComboBoxes should display the corresponding selected item according to the DataBase.

At the DataBase the values will be 10, 20, 30, 40 and the ComboBoxes should display Red, Blue, Green, Yellow respectively

QUESTION: HOW CAN I POPULATE THE DATAGRIDVIEW SO THAT EVERY COMBOBOX CELL HAS THE CORRESPONDING VALUE??

Answer

Here is a mocked example where I mock up data to simulate loading from a database. There is a label to show the ValueMember of the changed item when the user selects an item so you can do something with it if needed. Hope this is of interest.

''' <summary>
''' There are two columns in the DataGridView, both
''' have the DataProperty set to ParentId for the
''' first column a ComboBox, ChildName for the 
''' second column a text box.
''' </summary>
Public Class Form1
    WithEvents bsData1 As New BindingSource
    WithEvents bsData2 As New BindingSource
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        DataGridView1.AutoGenerateColumns = False
        bsData2.DataSource = GetParentTable()

        Column1.DisplayMember = "ParentName"
        Column1.ValueMember = "ParentID"
        Column1.DataSource = bsData2
        Column1.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing

        bsData1.DataSource = GetChildTable()
        DataGridView1.DataSource = bsData1

        UpdateLabel()
    End Sub
    ''' <summary>
    ''' Mocked data, in an app would come from a database table
    ''' </summary>
    ''' <returns></returns>
    Private Function GetParentTable() As DataTable
        Dim dt As New DataTable

        With dt.Columns
            .Add("ParentID", GetType(Integer))
            .Add("ParentName", GetType(String))
        End With

        With dt.Rows
            .Add(10, "Red")
            .Add(20, "Blue")
            .Add(30, "Green")
        End With

        dt.AcceptChanges()

        Return dt
    End Function
    ''' <summary>
    ''' Mocked data, in an app would come from a database table
    ''' </summary>
    ''' <returns></returns>
    Private Function GetChildTable() As DataTable
        Dim dt As New DataTable

        With dt.Columns
            .Add("ChildID", GetType(Integer))
            .Add("ParentID", GetType(Integer))
            .Add("ChildName", GetType(String))
        End With

        With dt.Rows
            .Add(1, 30, "Child 1")
            .Add(2, 20, "Child 2")
            .Add(3, 10, "Child 3")
        End With

        dt.AcceptChanges()

        Return dt

    End Function
    Private Sub DataGridView1_CellEndEdit(
        sender As Object,
        e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit

        UpdateLabel()

    End Sub
    Private Sub bsData1_PositionChanged(sender As Object, e As EventArgs) Handles bsData1.PositionChanged
        UpdateLabel()
    End Sub
    Private Sub UpdateLabel()
        If bsData1.DataSource IsNot Nothing Then
            If bsData1.Current IsNot Nothing Then
                Label1.Text = CType(bsData1.Current, DataRowView).Row.Field(Of Integer)("ParentID").ToString
            End If
        End If
    End Sub
End Class