Es kann ein wenig hacky sein, aber es sollte tun, was Sie fragen ... hoffentlich. Ich habe zwei List(Of String)
Variablen erstellt. AllRacers
enthält alle Rennfahrer ... d. H. Alle Namen, die in einem Kombinationsfeld angezeigt werden sollen, so dass kein anderes Kombinationsfeld in dieser Reihe ein Element ausgewählt hat. Diese Namen werden alle Kombinationsfelder in allen Zeilen ursprünglich in der Liste auswählbarer Elemente enthalten. Die andere List(Of String)
UsedRacers
enthält eine Liste aller "Comboboxen" in der aktuellen Zeile, die Elemente ausgewählt haben. Jedes Mal, wenn ein Zellenwert geändert wird und es sich um eine der "combobox" -Spaltenzellen handelt, wird UsedRacers
gelöscht/aktualisiert, um das hinzugefügte/geänderte ausgewählte Element in der aktuellen Zeile widerzuspiegeln.
Wenn ein „comboBox“ Zellwert geändert wird, SetUsedRacersForRow
genannt ...
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
Der obigen Code einer Schleife durch alle „Combobox“ Zellen in der gegebenen Reihe und wenn eine „Combobox“ Zelle etwas ausgewählt hat Der ausgewählte Wert wird zur Liste UsedRacers
hinzugefügt.
Jetzt, da die ausgewählten Elemente für alle "Comboboxen" in dieser Zeile in der UsedRacers
Liste sind, können wir nun jede "Combobox" -Zelle in dieser Zeile durchlaufen und die richtige Liste von Namen festlegen. Um zu helfen, wird eine Methode erstellt, die DataGridViewComboBoxCell
zurückgibt, so dass die Namen in der aktuellen UsedRacers
Liste NICHT in der DataGridViewComboBoxCell
Liste der auswählbaren Namen sind.
Das einzige Problem hier wäre mit Zellen, die derzeit ein Element ausgewählt haben. Für jede "Combobox" -Zelle mit einem ausgewählten Objekt muss der ausgewählte Eintrag eindeutig in der Liste der Elemente enthalten sein. Um dies zu beheben, muss überprüft werden, ob die Zelle "combobox" einen Wert enthält. Enthält die "combobox" -Zelle einen ausgewählten Wert, dann ist dieser Wert auch in der UsedRacers
-Liste enthalten. Da DIESE Zelle die Zelle ist, die in der UseRacers
Liste ist ... müssen wir diesen Wert zu dieser Zellenelementliste HINZUFÜGEN. Andernfalls könnten wir die eindeutige Auswahl nicht anzeigen.
Um die UsedRacers
Liste konsistent zu halten, müssen wir dieses Element direkt zu der einzelnen "Combobox" -Zelle hinzufügen und nicht die UsedRacers
Liste entfernen oder ändern, da dies für die anderen "Combobox" -Zellen verwendet wird.Mit anderen Worten ... welcher Wert in einem Kombinationsfeld ausgewählt wird, wir müssen sicherstellen, dass es sich um eines der Elemente in der Liste der auswählbaren Elemente der "Combobox" handelt. Ich hoffe das ergibt Sinn.
Dies kann alles im DataGridViews
CellChanged
Ereignis getan werden.
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
In dem obigen Code wird ein Verfahren GetCurrentComboBoxCell
(unten) ein DataGridViewComboBoxCell
so gibt, dass die Elemente in der Combo-Boxen Liste der Elemente keine Elemente enthalten, die in der UsedRacers
Liste enthalten sind. Aus diesem Grund ist eine Überprüfung erforderlich (siehe oben), um festzustellen, ob die Zelle bereits einen Wert enthält. HINWEIS: Die zurückgegebene DataGridViewComboBoxCell
enthält immer ein "leeres" leeres Element. Dies ist erforderlich, um dem Benutzer zu ermöglichen, einen aktuell ausgewählten Wert zu "deaktivieren" und dann den "De-Selected" -Element für die anderen Kombinationsfeldzellen verfügbar zu machen.
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
Schließlich all diese Zusammenstellung ...
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
Ich hoffe, das hilft, ich vermute es einen einfacheren Weg, dies zu tun ist.
Es gibt normalerweise keine 'ComboBox'-Steuerelemente in der Spalte und nie mehr als eins, so dass es nie erforderlich ist, zu bestimmen, auf welches geklickt wurde. Im Event-Handler 'EditingControlShowing' kann über die Eigenschaft 'e.Control' auf die einzige' ComboBox' zugegriffen werden. – jmcilhinney
Es ist unklar, was die Kombinationsfelder enthalten sollen. Der gebuchte Code scheint zahlreiche Kombinationsfeldspalten zu erstellen. Es gibt jedoch im verbuchten Code keine Elemente, die diesen Kombinationsfeldern Elemente hinzufügen. Können Sie klären, was die Kombinationsfelder enthalten sollen? Entweder haben sie alle die gleichen Werte oder jeder hat seine eigenen Werte, aber der Code tut dies auch nicht. – JohnG
@JohnG Die Idee war, dass ich gesendet werden würde, welche Combobox der Benutzer klickte, und ich konnte es dann zur Laufzeit auffüllen. –