Bind and Show a ComboBox in a DataGridView Cell – Windows Application

February 01st, 2013
DataGridView control is used to display data in tabular format. Its use is not limited to just displaying data, but it’s a perfect tool for doing data manipulation by binding it with a database. With its many useful features the DataGridView can be made to function like an Excel sheet.

ComboBox in DataGridView

In this article we will “Bind a ComboBox” with the DataGridView which will be displayed in “Cells” of a particular “Column”. The “ComboBox” will be useful when the user has to select data from a pre defined list of data. (Like master data).

Start “Microsoft Visual Studio” and select a “New Project” from “File” (Left Top Menu). From the “New Project” templates, select “Windows Forms Application” and click OK.

1) A new project appears with a “Blank Form”. Click the “Toolbox” button and from the list of tools “Double Click” to add a “DataGridView” control on the form.

2) Select the “DataGridView” and “Right Click” the mouse, to select “Properties”. In the “DataGridView Properties” window, select “Columns” and add few columns to the grid.

DataGridView Design Mode

3) Finally drag and drop a “ComboBox” control on the “DataGridView” itself. The “ComboBox” will have a list of “Qualifications”. So add a few items in the ComboBox. Right click it to open the properties window. Find the “Items” property and add items to it. Also set the “Visible” property of the ComboBox as “False”. We don’t want the ComboBox to be visible when the form has loaded at runtime. The ComboBox will be visible when the focus is on a “Cell” corresponding to the “Qualification Column”. Till then it will be kept hidden.

Note: The “ComboBox” control should be placed on the “DataGridView” control.

We now write our code.

This demo application will add new employee details to the database. So we have added 5 columns to the Grid as shown in the above image. We want to show a list of “Qualifications” with the help of a ComboBox when the focus is on a “Cell” corresponding to the “Qualification” column.

Code (Form1.vb)
Option Explicit On

Public Class frmDataGridView_Demo
    Dim dtTable As New DataTable("Employee")    ' CREATE A DATATABLE.

    Private Sub frmDataGridView_Demo_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
            Handles Me.Load
        AddRows()                ' ADD FEW BLANK ROWS TO START WITH.
    End Sub

    Private Sub AddRows()
        Dim row As DataRow
        row = dtTable.NewRow

        For iCntCol = 1 To 10
            row = dtTable.NewRow        ' ADD BLANK ROWS TO THE DATATABLE.
            dtTable.Rows.Add(row)
        Next

        With DataGridView1
            .DataSource = dtTable       ' ADD DATATABLE TO GRID. (WITH THE BLANK ROWS)

            ' JUST FOR THE LOOKS.
            .GridColor = Color.FromArgb(211, 222, 229)
            .BackgroundColor = Color.Wheat

            .RowsDefaultCellStyle.BackColor = Color.AliceBlue
            .RowsDefaultCellStyle.SelectionBackColor = Color.CornflowerBlue
            .RowsDefaultCellStyle.SelectionForeColor = Color.White
        End With
    End Sub

    ' CONTROL THE KEY STROKES.
    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, _
            ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = Keys.Enter Then

            ' ON ENTER KEY, GO TO THE NEXT CELL. 
                ' WHEN THE CURSOR REACHES THE LAST COLUMN, CARRY IT ON TO THE NEXT ROW.

            If ActiveControl.Name = "DataGridView1" Then
                With DataGridView1
                    If .CurrentCell.ColumnIndex = .ColumnCount - 1 Then             ' CHECK IF ITS THE LAST COLUMN
                        .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(0)    ' GO TO THE FIRST COLUMN, NEXT ROW.
                    Else
                        .CurrentCell = .Rows(.CurrentRow.Index).Cells(.CurrentCell.ColumnIndex + 1)     ' NEXT COLUMN.
                    End If
                End With
            ElseIf TypeOf ActiveControl Is DataGridViewTextBoxEditingControl Then

                ' SHOW THE COMBOBOX WHEN FOCUS IS ON A CELL CORRESPONDING TO THE "QUALIFICATION" COLUMN.
                With DataGridView1
                    If .Columns(.CurrentCell.ColumnIndex).Name = "Address" Then
                        .CurrentCell = .Rows(.CurrentRow.Index).Cells(.CurrentCell.ColumnIndex + 1)
                        Show_Combobox(.CurrentRow.Index, .CurrentCell.ColumnIndex)      ' SHOW COMBOBOX.

                        SendKeys.Send("{F4}")               ' DROP DOWN THE LIST.
                    Else
                        If .CurrentCell.ColumnIndex = .ColumnCount - 1 Then             ' CHECK IF ITS THE LAST COLUMN
                            .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(0)    ' GO TO THE FIRST COLUMN, NEXT ROW.
                        Else
                            .CurrentCell = .Rows(.CurrentRow.Index).Cells(.CurrentCell.ColumnIndex + 1)     ' NEXT COLUMN.
                        End If
                    End If
                End With
            ElseIf ActiveControl.Name = "ComboBox1" Then
                ' HIDE THE COMBOBOX AND ASSIGN COMBO'S VALUE TO THE CELL.
                ComboBox1.Visible = False

                With DataGridView1
                    .Focus()            ' ONCE THE COMBO IS SET AS INVISIBLE, SET FOCUS BACK TO THE GRID. (IMPORTANT)
                    .Item(.CurrentCell.ColumnIndex, .CurrentRow.Index).Value = Trim(ComboBox1.Text)
                    .CurrentCell = .Rows(.CurrentRow.Index).Cells(.CurrentCell.ColumnIndex + 1)
                End With
            Else
                SendKeys.Send("{TAB}")
            End If
            Return True

        ElseIf keyData = Keys.Escape Then       ' PRESS ESCAPE TO HIDE THE COMBOBOX.
            If ActiveControl.Name = "ComboBox1" Then
                ComboBox1.Text = "" : ComboBox1.Visible = False

                With DataGridView1
                    .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex)
                    .Focus()
                    Return True
                End With
            End If
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
    End Function

    Private Sub Show_Combobox(ByVal iRowIndex As Integer, ByVal iColumnIndex As Integer)
        ' DESCRIPTION: SHOW THE COMBO BOX IN THE SELECTED CELL OF THE GRID.
        ' PARAMETERS: iRowIndex - THE ROW ID OF THE GRID.
        '             iColumnIndex - THE COLUMN ID OF THE GRID.

        Dim x As Integer = 0
        Dim y As Integer = 0
        Dim Width As Integer = 0
        Dim height As Integer = 0

        ' GET THE ACTIVE CELL'S DIMENTIONS TO BIND THE COMBOBOX WITH IT.
        Dim rect As Rectangle
        rect = DataGridView1.GetCellDisplayRectangle(iColumnIndex, iRowIndex, False)
        x = rect.X + DataGridView1.Left
        y = rect.Y + DataGridView1.Top

        Width = rect.Width
        height = rect.Height

        With ComboBox1
            .SetBounds(x, y, Width, height)
            .Visible = True
            .Focus()
        End With
    End Sub
End Class
advertise here
comments powered by Disqus

Join our Google Plus Community and be a part of a discussion!