DataGridView Каскадные / зависимые столбцы ComboBox
Поэтому я время от времени работаю в Winforms над устаревшим приложением и не всегда знаком с рекомендациями по связыванию объектов. По сути, у меня есть набор из трех частей, где у меня есть два человека, у них может быть только один продукт, но этот продукт может вызвать возможность иметь разные наборы SKU. Есть ли способ вызвать событие и заполнение комбинированного списка из значений первого комбинированного списка? Я оглядываюсь по сторонам и нахожу либо базовые данные о том, как связать комбо-бокс (я могу сделать это нормально), либо что-то сделать с тем, как вы его связываете. Не связывание после того, как смена зависимого родителя инициируется и происходит изменение набора данных. Пример ниже:
Pocos:
Public Class Person
Public Property PersonID As Integer
Public Property FirstName As String
Public Property LastName As String
Public Property ProductId As Integer
Public Property SkuId As Integer
End Class
Public Class Product
Public Property ProductId As Integer
Public Property Description As String
End Class
Public Class Sku
Public Property SKUId As Integer
Public Property ProductId As Integer
Public Property Description As String
End Class
Пример основного кода (базовый интерфейс пользователя на самом деле имеет только набор данных с меткой ds, который почти идентично сопоставляет POCOS Person и Product с таблицами данных. Представление datagrid, столбцы которого связаны с данными в Person EXCEPT для столбца с именем SKU, не имеет привязки поскольку я хочу связать это после факта, и это - то, где я терплю неудачу с треском.
Обновление 9-13-2016 Я могу заставить приведенный ниже код работать, КРОМЕ в определенных крупномасштабных решениях (по этой причине я так и сделал). Он в основном НЕ будет выполнять строку, которая преобразует ячейку () в блок данных dvagridview, игнорирует его и перепрыгивает через строку. Нет причин, почему он просто перепрыгивает через это. Мне интересно, могут ли представления больших массивов данных объединяться в таблицы или что-то в этом роде.
Основной код:
Private _people As List(Of Person) = New List(Of Person)
Private _products As List(Of Product) = New List(Of Product)
Private _SKUs As List(Of Sku) = New List(Of Sku)
Private _initialLoadDone = False
Private _currentRow As Integer? = Nothing
Private Sub DynamicComboBoxDoubleFill_Load(sender As Object, e As EventArgs) Handles MyBase.Load
_products = New List(Of Product)({
New Product With {.ProductId = 1, .Description = "Offline"},
New Product With {.ProductId = 2, .Description = "Online"}
})
Dim s = ""
For Each o In _products
Dim row As DataRow = ds.Tables("tProducts").NewRow
row("ProductId") = o.ProductId
row("Description") = o.Description
ds.Tables("tProducts").Rows.Add(row)
Next
_SKUs = New List(Of Sku)({
New Sku With {.SKUId = 1, .ProductId = 1, .Description = "Mail"},
New Sku With {.SKUId = 2, .ProductId = 1, .Description = "Magazine"},
New Sku With {.SKUId = 3, .ProductId = 2, .Description = "Email"},
New Sku With {.SKUId = 4, .ProductId = 2, .Description = "APIRequest"}
})
Dim items = _SKUs
_people = New List(Of Person)({
New Person With {.PersonID = 1, .FirstName = "Emily", .LastName = "X", .ProductId = 1, .SkuId = 1},
New Person With {.PersonID = 2, .FirstName = "Brett", .LastName = "X", .ProductId = 2, .SkuId = 3}
})
For Each p In _people
Dim row As DataRow = ds.Tables("tPeople").NewRow
row("PersonId") = p.PersonId
row("FirstName") = p.FirstName
row("LastName") = p.LastName
row("ProductId") = p.ProductId
row("SkuId") = p.SkuId
ds.Tables("tPeople").Rows.Add(row)
Next
For Each row As DataGridViewRow In dgv.Rows
ArrangeValuesForSKUComboBox(row)
Next
_initialLoadDone = True
End Sub
Private Sub ArrangeValuesForSKUComboBox(row As DataGridViewRow)
Dim productId = CInt(row.Cells("ProductId")?.Value)
Dim skus = _SKUs.Where(Function(x) x.ProductId = productId).ToList().Select(Function(x) New With {Key .SkuId = x.SKUId, .SkuDesc = x.Description}).ToList()
Dim cell = row.Cells("SKU")
'Yeah I don't always work. In this example I do, in others I won't.
'For this reason I just want more ideas. I don't care if you completely blow up how the binding is done and do something else entirely.
Dim combobox = CType(cell, DataGridViewComboBoxCell)
combobox.DataSource = skus
combobox.ValueMember = "SKUId"
combobox.DisplayMember = "SkuDesc"
combobox.Value = skus.FirstOrDefault()?.SkuId
End Sub
Private Sub dgv_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgv.CellValueChanged
If _initialLoadDone Then
Dim headerText As String = TryCast(sender, DataGridView).Columns(e.ColumnIndex).HeaderText
If headerText = "PRODUCT" Then
ArrangeValuesForSKUComboBox(dgv?.CurrentRow)
End If
End If
End Sub