它可能有點不好意思,但它應該做你在問什麼...希望。我創建了兩個List(Of String)
變量。 AllRacers
包含所有賽車運動員......即我們想要出現在組合框中的所有名稱,使得在該行上沒有其他組合框已經選擇了項目。這些名稱是所有行上的所有組合框最初將包含在可選項列表中的名稱。
其他List(Of String)
UsedRacers
包含當前行中具有所選項目的所有「組合框」的列表。每當單元格值發生更改並且它是「組合框」列單元格之一時,則清除/更新UsedRacers
以反映當前行上添加/更改的選定項目。
當「組合框」單元格的值發生變化,SetUsedRacersForRow
叫...
Private Sub SetUsedRacersForRow(rowIndex As Int16)
UsedRacers.Clear()
Dim curValue = ""
For i = 1 To racersPerShift
If (Not (dgvRacers.Rows(rowIndex).Cells(i).Value Is Nothing)) Then
curValue = dgvRacers.Rows(rowIndex).Cells(i).Value.ToString()
If (Not (String.IsNullOrEmpty(curValue))) Then
UsedRacers.Add(curValue)
End If
End If
Next
End Sub
上面的代碼通過給定行中,如果一個「組合框」小區已經什麼選擇所有的「組合框」細胞循環,所選值將被添加到UsedRacers
列表中。
現在,該行中所有「組合框」的選定項都在UsedRacers
列表中,我們現在可以遍歷該行中的每個「組合框」單元並設置正確的名稱列表。爲了提供幫助,會創建一個返回DataGridViewComboBoxCell
的方法,使當前的UsedRacers
列表中的名稱不在DataGridViewComboBoxCell
的可選名稱列表中。
這裏唯一的問題是當前選中某個項目的單元格。每個包含所選項目的「組合框」單元格都將唯一需要在其項目列表中包含所選項目。爲了解決這個問題,需要檢查「組合框」單元是否包含一個值。如果「組合框」單元格包含選定值,則該值也包含在UsedRacers
列表中。由於此單元格是UseRacers
列表中的單元格,因此我們需要將此值添加到此單元格項目列表中。否則,我們將無法顯示唯一的選擇。
要保持UsedRacers
列表一致,我們需要直接將此項添加到單個「組合框」單元中,而不是刪除或更改列表,因爲這將用於其他「組合框」單元。換句話說,無論在組合框中選擇了什麼值,我們都需要確保它是「組合框」可選項列表中的項目之一。我希望這是有道理的。
這可以全部在DataGridViews
CellChanged
事件中完成。
Private Sub dgvRacers_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvRacers.CellValueChanged
If (e.ColumnIndex >= 1 And e.ColumnIndex <= racersPerShift) Then
SetUsedRacersForRow(e.RowIndex)
For i = 1 To racersPerShift
Dim newCell As DataGridViewComboBoxCell = GetCurrentComboBoxCell()
If (Not (dgvRacers.Rows(e.RowIndex).Cells(i).Value Is Nothing)) Then
Dim curValue = dgvRacers.Rows(e.RowIndex).Cells(i).Value.ToString()
newCell.Items.Add(curValue)
newCell.Value = curValue
End If
dgvRacers.Rows(e.RowIndex).Cells(i) = newCell
Next
End If
End Sub
在上面的代碼中,一種方法GetCurrentComboBoxCell
(下面)返回一個DataGridViewComboBoxCell
,使得在項目的組合框列表中的項不包含在該列表中UsedRacers
任何項目。因此,需要檢查(上面)以查看單元格是否已包含值。注意:DataGridViewComboBoxCell
返回將始終包含一個「空白」空項目。這是允許用戶「取消選擇」任何當前選定的值,然後使「取消選定」項目可用於其他組合框單元所必需的。
Public Function GetCurrentComboBoxCell() As DataGridViewComboBoxCell
Dim newComboCell = New DataGridViewComboBoxCell()
newComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
newComboCell.FlatStyle = FlatStyle.Flat
newComboCell.Items.Add("")
For Each curRacer In AllRacers
If (Not UsedRacers.Contains(curRacer)) Then
newComboCell.Items.Add(curRacer)
End If
Next
Return newComboCell
End Function
最後,把所有這些組合起來......
Dim racersInShift = 3
Dim AllRacers As List(Of String) = New List(Of String) From {"John", "Bobby", "Trent", "Josh", "Chapman", "Henry", "George", "Marvin"}
'Dim racersPerShift As Int16 = AllRacers.Count '<-- should be MAX value
Dim racersPerShift As Int16 = 4
Dim UsedRacers = New List(Of String)
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BuildGrid()
End Sub
Private Sub BuildGrid()
dgvRacers.Size = New Size(800, 200)
dgvRacers.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
'dgvRacers.Location = New Point(50, 200)
dgvRacers.Columns.Add("ShiftCOL", "Shift Name")
dgvRacers.Name = "RacersDGV"
dgvRacers.EditMode = DataGridViewEditMode.EditOnEnter
dgvRacers.AllowUserToAddRows = False
AddRacerColumns()
AddRacerRows()
End Sub
Private Sub AddRacerColumns()
Dim newColumn As DataGridViewComboBoxColumn
For i As Integer = 1 To racersPerShift
newColumn = GetNewComboBoxColumn("Racer" & i, "Racer " & i)
dgvRacers.Columns.Add(newColumn)
Next
End Sub
Private Sub AddRacerRows()
For i As Integer = 1 To racersInShift
Dim row As New DataGridViewRow
dgvRacers.Rows.Add(row)
Next
End Sub
Private Sub dgvRacers_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs)
‘See code above
End Sub
Private Sub SetUsedRacersForRow(rowIndex As Int16)
‘See code above
End Sub
Public Function GetCurrentComboBoxCell() As DataGridViewComboBoxCell
‘See code above
End Function
‘Lastly a method to set a whole `DataGridviewComboBoxColumn` which is used to initialize all the combo box columns
Public Function GetNewComboBoxColumn(colName As String, colHeader As String) As DataGridViewComboBoxColumn
Dim newComboCol = New DataGridViewComboBoxColumn()
newComboCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
newComboCol.FlatStyle = FlatStyle.Flat
newComboCol.Items.Add("")
newComboCol.HeaderText = colHeader
newComboCol.Name = colName
For Each curRacer In AllRacers
newComboCol.Items.Add(curRacer)
Next
Return newComboCol
End Function
我希望這可以幫助,我猜還有一個更簡單的方法來做到這一點。
列中通常沒有'ComboBox'控件,並且從不超過一個,因此從不需要確定哪個被點擊。在EditingControlShowing事件處理程序中,唯一的'ComboBox'可以通過'e.Control'屬性訪問。 – jmcilhinney
目前還不清楚你想要組合框包含什麼。發佈的代碼似乎會生成許多組合框列,但是發佈的代碼中沒有任何內容將項目添加到這些組合框。你能澄清你想要組合框包含什麼嗎?它們都具有相同的值,或者每個都有自己的值,但代碼都不具備。 – JohnG
@JohnG想法是,我將被髮送到用戶點擊的任何組合框,然後我可以在運行時填充它。 –