VB.Net DataGridView ComboBox:如何获取未保存的显示文本?
解决DataGridView ComboBox列自定义输入丢失问题
你的问题核心在于用KeyDown事件手动拼接输入内容的方式太不可靠——键盘输入的场景太多(比如粘贴、输入法输入、特殊字符组合),很容易漏处理或者逻辑出错,而且直接修改列Items的时机不对也会引发异常。
其实不用这么麻烦,我们可以利用控件的Validating事件,在ComboBox失去焦点(比如用户按Tab切换)的瞬间,直接获取编辑控件的完整输入文本,再做后续处理。这样既能准确拿到用户输入的内容,又能避免KeyDown的各种坑。
改进后的代码实现
Private Sub dGrid1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles dGrid1.EditingControlShowing If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then ' 先移除之前的事件绑定,避免重复绑定 RemoveHandler e.Control.Validating, AddressOf ComboBox_Validating Dim comboBox As ComboBox = CType(e.Control, ComboBox) ' 设置允许自定义输入 comboBox.DropDownStyle = ComboBoxStyle.DropDown comboBox.AutoCompleteSource = AutoCompleteSource.ListItems comboBox.AutoCompleteMode = AutoCompleteMode.Suggest ' 绑定Validating事件,在控件失去焦点前处理输入 AddHandler comboBox.Validating, AddressOf ComboBox_Validating End If End Sub Private Sub ComboBox_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Dim comboBox As DataGridViewComboBoxEditingControl = CType(sender, DataGridViewComboBoxEditingControl) Dim inputText As String = comboBox.Text.Trim() ' 如果输入不为空,且不在下拉列表中 If Not String.IsNullOrEmpty(inputText) AndAlso Not comboBox.Items.Contains(inputText) Then ' 获取当前编辑的列(注意是DataGridViewComboBoxColumn) Dim comboColumn As DataGridViewComboBoxColumn = CType(dGrid1.Columns(dGrid1.CurrentCell.ColumnIndex), DataGridViewComboBoxColumn) ' 先检查列的Items里有没有,避免重复添加 If Not comboColumn.Items.Contains(inputText) Then ' 添加到列的下拉列表,后续行也能用到 comboColumn.Items.Add(inputText) End If ' 把当前单元格的值设置为用户输入的文本,避免被清空 dGrid1.CurrentCell.Value = inputText End If End Sub
为什么这个方案更可靠?
- 准确获取完整输入:
Validating事件触发时,用户的所有输入(包括粘贴、输入法输入的内容)都已经写入到comboBox.Text里了,不需要手动拼接,完全避免了KeyDown处理特殊字符的复杂逻辑。 - 避免异常:我们只在确认输入不在列表中时才添加到列的Items,而且是在控件即将失去焦点的安全时机操作,不会和DataGridView的编辑状态冲突。
- 自动保留输入:直接把
CurrentCell.Value设置为输入文本,这样DataGridView就不会因为值不在下拉列表而清空内容了。
额外提示
如果你的DataGridView是绑定了数据源的,记得要确保数据源的对应字段支持自定义值(比如不要设置为只能选列表项的约束),不过根据你的描述数据集是空的或者只有未完成订单,这个应该不是问题。
内容的提问来源于stack exchange,提问作者J Campbell
相关产品推荐
相关产品推荐

