【发布时间】:2015-07-01 04:22:32
【问题描述】:
我有一个 winforms DataGridView,我希望有一个包含每条记录的组合框的列。每个组合框的每一行都将具有完全不同的值,并且需要在 DataGridView 的数据绑定期间分配一个数据源。我可以为所有数据源分配 1 个数据源(这很容易),但是让每个组合框都有不同的值看起来是不可能的)。
这是我正在使用的 - 注意:DataGridView 的数据源是通过设置调用表单的属性以编程方式定义的。
Public Class frmSendToQuickbooksPopup
Public Property CurrentOrder As OrderICT
Public Property lineitems As List(Of OrderLineItemICT)
Private Sub frmSendToQuickbooksPopup_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'define the combobox (datasource can't be assigned here as each will be different for each row)
Dim dgvcboMatch As New DataGridViewComboBoxColumn
dgvcboMatch.DisplayMember = "Name"
dgvcboMatch.ValueMember = "ListID"
dgvcboMatch.HeaderText = "Matches"
dgvcboMatch.Name = "Match"
dgvcboMatch.Width = 150
dgvLineItems.Columns.Add(dgvcboMatch)
Me.dgvLineItems.DataSource = lineitems
End Sub
Private Sub dgvLineItems_DataSourceChanged(sender As Object, e As EventArgs) Handles dgvLineItems.DataSourceChanged
Dim L As New QBI.OrderLineItemICT
With L
dgvLineItems.Columns(.col_LineItemBvin).Visible = False
dgvLineItems.Columns(.col_ProductId).Visible = False
dgvLineItems.Columns(.col_ProductShortDescription).Visible = False
dgvLineItems.Columns(.col_ShippingBoxCount).Visible = False
dgvLineItems.Columns(.col_CustomProperties).Visible = False
dgvLineItems.Columns(.col_ShippingLength).Visible = False
dgvLineItems.Columns(.col_ShippingWidth).Visible = False
dgvLineItems.Columns(.col_ShippingHeight).Visible = False
dgvLineItems.Columns(.col_ProductName).DisplayIndex = 2
dgvLineItems.Columns(.col_ProductName).HeaderText = "Product Name"
dgvLineItems.Columns(.col_ProductName).Width = 170
dgvLineItems.Columns(.col_ProductSku).HeaderText = "SKU"
dgvLineItems.Columns(.col_ProductSku).Width = 160
dgvLineItems.Columns(.col_Quantity).DefaultCellStyle.Format = "n0"
dgvLineItems.Columns(.col_Quantity).DisplayIndex = 7
dgvLineItems.Columns(.col_Quantity).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
dgvLineItems.Columns(.col_Quantity).Width = 65
dgvLineItems.Columns(.col_AdjustedPrice).DefaultCellStyle.Format = "c2"
dgvLineItems.Columns(.col_AdjustedPrice).HeaderText = "Adj Price"
dgvLineItems.Columns(.col_AdjustedPrice).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
dgvLineItems.Columns(.col_AdjustedPrice).Width = 80
dgvLineItems.Columns(.col_BasePrice).DefaultCellStyle.Format = "c2"
dgvLineItems.Columns(.col_BasePrice).HeaderText = "Base Price"
dgvLineItems.Columns(.col_BasePrice).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
dgvLineItems.Columns(.col_BasePrice).Width = 85
dgvLineItems.Columns(.col_Discounts).DefaultCellStyle.Format = "c2"
dgvLineItems.Columns(.col_Discounts).HeaderText = "Discounts"
dgvLineItems.Columns(.col_Discounts).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
dgvLineItems.Columns(.col_Discounts).Width = 80
dgvLineItems.Columns(.col_LineTotal).DefaultCellStyle.Format = "c2"
dgvLineItems.Columns(.col_LineTotal).HeaderText = "Line Total"
dgvLineItems.Columns(.col_LineTotal).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
dgvLineItems.Columns(.col_LineTotal).Width = 80
dgvLineItems.Columns(.col_UOM).DisplayIndex = 9
dgvLineItems.Columns(.col_UOM).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
dgvLineItems.Columns(.col_UOM).HeaderText = "Units"
dgvLineItems.Columns(.col_UOM).Width = 55
dgvLineItems.Columns(.col_ShippingWeight).DisplayIndex = 10
dgvLineItems.Columns(.col_ShippingWeight).HeaderText = "Unit Wt"
dgvLineItems.Columns(.col_ShippingWeight).DefaultCellStyle.Format = "N1"
dgvLineItems.Columns(.col_ShippingWeight).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
dgvLineItems.Columns(.col_ShippingWeight).Width = 70
End With
End Sub
Public Function GetComboboxData(ProductNameToMatch As String, ProductSKUToMatch As String) As List(Of WPM_Item)
'this function returns a list of returned matches for a given row's ProductName or SKU
'this function will be the datasource for a given combobox
Dim itms As New List(Of WPM_Item)
itms = WPM_Data.FindWPM_ItemMatch(ProductNameToMatch, ProductSKUToMatch)
Return itms
End Function
End Class
如果有某种方法可以拦截 DataGridView 的数据绑定,以便我可以从另一个单元格获取值(以调用另一个过程),然后使用返回数据填充每一行的组合框。这很容易使用 webforms,但我没有看到 winforms 版本的事件。
我尝试过的另一件事,但不起作用(组合框数据源消失了!)
Private Sub dgvLineItems_DataBindingComplete(sender As Object, e As DataGridViewBindingCompleteEventArgs) Handles dgvLineItems.DataBindingComplete
For Each row As DataGridViewRow In Me.dgvLineItems.Rows
Dim dr = DirectCast(row.DataBoundItem, OrderLineItemICT)
If dr Is Nothing Then
Return
End If
Dim name As String = row.Cells(dr.col_ProductName).Value.ToString
Dim SKU As String = row.Cells(dr.col_ProductSku).Value.ToString
Dim cell As DataGridViewComboBoxCell = TryCast(row.Cells("Match"), DataGridViewComboBoxCell)
cell.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox
Dim wpm_items As List(Of WPM_Item) = GetComboboxData(name, SKU)
If cell.DataSource Is Nothing Then
cell.DataSource = wpm_items 'this forgets the datasource, why?
cell.DisplayMember = "Name"
cell.ValueMember = "ListID"
cell.Value = wpm_items.Item(0).Name 'this always throws an error "DataGridViewComboBoxCell value is not valid."
End If
Next
End Sub
这是同一分配的另一个版本,这次组合框填充了 add 方法。 (仍然不记得这些值) 我基本上遵循了另一个论坛的想法 - 也许 DotNet 4.5 DataGridView 有一个错误。
Private Sub dgvLineItems_DataBindingComplete(sender As Object, e As DataGridViewBindingCompleteEventArgs) Handles dgvLineItems.DataBindingComplete
For Each row As DataGridViewRow In Me.dgvLineItems.Rows
Dim dr = DirectCast(row.DataBoundItem, OrderLineItemICT)
If dr Is Nothing Then
Return
End If
Dim name As String = row.Cells(dr.col_ProductName).Value.ToString
Dim SKU As String = row.Cells(dr.col_ProductSku).Value.ToString
Dim cell As DataGridViewComboBoxCell = DirectCast(row.Cells("Match"), DataGridViewComboBoxCell)
cell.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox
Dim wpm_items As List(Of WPM_Item) = GetComboboxData(name, SKU)
'THIS DOES NOT WORK EITHER!!
cell.DisplayMember = "Name"
cell.ValueMember = "ListID"
For Each wItm As WPM_Item In wpm_items
Dim c As New comboboxitem
c.Text = wItm.Name
c.Value = wItm.ListID
cell.Items.Add(c)
Next
Next
End Sub
Public Class ComboboxItem
Public Property Text() As String
Public Property Value() As Object
Public Overrides Function ToString() As String
Return Text
End Function
End Class
【问题讨论】:
标签: vb.net winforms datagridview combobox