vb.net 教程 3-10 窗体编程 datagridview控件 17 实现文本单元格中显示下拉框并设置值(续)

上一节中实现了在文本单元格中显示下拉框并在选择值后将值写入到单元格

但是在实际使用中,会发现一些问题:

1、由于设置的单元格是第一列,当选择了一个值后,并不会像datagridviewcomboboxcell或者datagridviewtextcell这些,选择了值或者输入了值,最下面就会出来新的一行,而要在其他列输入数据后才会出来新行。这也是网上很多代码没有解决的问题。

vb.net 教程 3-10 窗体编程 datagridview控件 17 实现文本单元格中显示下拉框并设置值(续)

2、当点击了第一列某个单元格,下拉框出来后,不选择值而是在其他列的表格中点击了一下,那么之前点击出现的下拉框不会消失。

vb.net 教程 3-10 窗体编程 datagridview控件 17 实现文本单元格中显示下拉框并设置值(续)

3、当点击了第一列某个单元格,即使下拉框出来后,也可以输入数据,而不是期望的从下拉框中的数据。

vb.net 教程 3-10 窗体编程 datagridview控件 17 实现文本单元格中显示下拉框并设置值(续)

解决以上问题,

1、在向单元格写入数据后通知datagridview做了修改

        dgv.NotifyCurrentCellDirty(True)
        dgv.NotifyCurrentCellDirty(False)

实测需要两次通知,一次有时候不行。

2、当点击其它列单元格的时候,隐藏下拉框

3、设置单元格只读:ReadOnly = True

修改后的代码如下:


    Dim cb As ComboBox
    Dim cellrowindex, cellcolindex As Integer


    Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        cb = New ComboBox
        cb.Items.Add("甲甲甲甲")
        cb.Items.Add("乙乙乙乙")
        cb.Items.Add("丙丙丙丙")
        cb.DropDownStyle = ComboBoxStyle.DropDownList
        cb.Visible = False
        dgv.Controls.Add(cb)
        AddHandler cb.SelectedIndexChanged, AddressOf cbChanged
    End Sub

    Private Sub cbChanged(ByVal sender As Object, ByVal e As EventArgs)
        dgv(cellcolindex, cellrowindex).Value = cb.Text
        cb.Visible = False
        dgv.NotifyCurrentCellDirty(True)
        dgv.NotifyCurrentCellDirty(False)
        'RemoveHandler cb.SelectedIndexChanged, AddressOf cbChanged
    End Sub

    Private Sub dgv_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgv.CellClick
        If e.RowIndex < 0 Then Exit Sub
        If e.ColumnIndex <> 0 Then
            cb.Visible = False
            Exit Sub
        End If

        cellcolindex = e.ColumnIndex
        cellrowindex = e.RowIndex
        Dim cellvalue As String = dgv(e.ColumnIndex, e.RowIndex).Value
        dgv(e.ColumnIndex, e.RowIndex).ReadOnly = True

        Dim rect As Rectangle
        rect = dgv.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True)
        cb.Top = rect.Top
        cb.Left = rect.Left
        cb.Width = rect.Width
        cb.Height = rect.Height

        If IsNothing(cellvalue) Then
            cb.Text = cb.Items(0)
        Else
            cb.Text = cellvalue
        End If

        cb.Visible = True

    End Sub

 

由于.net平台下C#和vb.Net很相似,本文也可以为C#爱好者提供参考。

学习更多vb.net知识,请参看vb.net 教程 目录