版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
上一节中实现了在文本单元格中显示下拉框并在选择值后将值写入到单元格。
但是在实际使用中,会发现一些问题:
1、由于设置的单元格是第一列,当选择了一个值后,并不会像datagridviewcomboboxcell或者datagridviewtextcell这些,选择了值或者输入了值,最下面就会出来新的一行,而要在其他列输入数据后才会出来新行。这也是网上很多代码没有解决的问题。
2、当点击了第一列某个单元格,下拉框出来后,不选择值而是在其他列的表格中点击了一下,那么之前点击出现的下拉框不会消失。
3、当点击了第一列某个单元格,即使下拉框出来后,也可以输入数据,而不是期望的从下拉框中的数据。
解决以上问题,
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 教程 目录