VB.NET中DataGridView的ComboBox选中项处理及重复项隐藏需求
发票模块DataGridView ComboBox列解决方案
一、选中商品时自动填充编码与金额
通过监听DataGridView的CellValueChanged事件,在商品选择列的值变更时,从绑定的商品实体中提取编码和金额,填充到对应单元格:
Private Sub dgvInvoice_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvInvoice.CellValueChanged ' 仅处理商品选择列,且排除新行 If e.ColumnIndex = colProduct.Name AndAlso Not dgvInvoice.Rows(e.RowIndex).IsNewRow Then Dim selectedProduct As Product = DirectCast(dgvInvoice.Rows(e.RowIndex).Cells(colProduct.Name).Value, Product) ' 填充商品编码单元格 dgvInvoice.Rows(e.RowIndex).Cells(colProductCode.Name).Value = selectedProduct.Code ' 填充商品金额单元格 dgvInvoice.Rows(e.RowIndex).Cells(colAmount.Name).Value = selectedProduct.Price End If End Sub
说明:Product为自定义实体类,需包含Code(商品编码)、Price(金额)等属性;colProduct是DataGridView中绑定商品列表的ComboBox列,其数据源需设置为Product类的集合。
二、后续行隐藏已选商品
利用EditingControlShowing事件获取当前编辑的ComboBox控件,动态过滤数据源,排除已在其他行选中的商品(编辑现有行时保留当前行的商品选项):
Private originalProductList As List(Of Product) ' 从数据库加载的完整商品列表 Private Sub dgvInvoice_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles dgvInvoice.EditingControlShowing Dim cbo As ComboBox = TryCast(e.Control, ComboBox) If cbo IsNot Nothing AndAlso dgvInvoice.CurrentCell.ColumnIndex = colProduct.Name Then ' 收集已选中的商品(排除当前编辑行) Dim selectedProducts As New List(Of Product) For Each row As DataGridViewRow In dgvInvoice.Rows If row.Index <> dgvInvoice.CurrentCell.RowIndex AndAlso Not row.IsNewRow Then Dim prod As Product = TryCast(row.Cells(colProduct.Name).Value, Product) If prod IsNot Nothing Then selectedProducts.Add(prod) End If Next ' 过滤数据源:保留未选中商品 + 当前行已选商品(编辑场景) Dim filteredProducts = originalProductList.Where(Function(p) Not selectedProducts.Contains(p) OrElse p.Equals(TryCast(dgvInvoice.CurrentRow.Cells(colProduct.Name).Value, Product)) End Function).ToList() ' 更新ComboBox数据源 cbo.DataSource = filteredProducts cbo.DisplayMember = "Name" ' 设置显示的商品名称字段 cbo.ValueMember = "Id" ' 设置绑定的商品标识字段(或直接绑定Product实体) End If End Sub
补充:删除行后恢复商品选项
当用户删除某一行的商品时,需刷新其他行的ComboBox选项,可监听UserDeletedRow事件:
Private Sub dgvInvoice_UserDeletedRow(sender As Object, e As DataGridViewRowEventArgs) Handles dgvInvoice.UserDeletedRow ' 触发所有行的编辑状态刷新,更新ComboBox数据源 For Each row As DataGridViewRow In dgvInvoice.Rows If Not row.IsNewRow Then dgvInvoice.BeginEdit(True) dgvInvoice.EndEdit() End If Next End Sub
内容的提问来源于stack exchange,提问作者John MacClain
相关产品推荐
相关产品推荐

