少しハッキリかもしれませんが、うまくいけばいいと思います。私は2つのList(Of String)
変数を作成しました。 AllRacers
には、すべてのレーサー、つまりコンボボックスに表示するすべての名前が含まれています。そのため、その行にアイテムが選択されているコンボボックスはありません。これらの名前は、すべての行のすべてのコンボボックスが最初に選択可能なアイテムリストに含まれるものです。
もう1つList(Of String)
UsedRacers
には、選択したアイテムを持つ現在の行のすべての「コンボボックス」のリストが含まれています。セル値が変更され、「コンボボックス」列セルの1つになるたびに、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
リストにあるので、その行の各「コンボボックス」セルをループし、適切な名前リストを設定できるようになりました。助けるために、現在のUsedRacers
リストの名前がDataGridViewComboBoxCell
の選択可能な名前のリストに含まれないようにDataGridViewComboBoxCell
を返すメソッドが作成されます。
ここで問題となるのは、現在アイテムが選択されているセルのみです。選択された項目を有する各「コンボボックス」セルは、選択された項目をその項目のリストに有する必要がある。この問題を解決するには、「コンボボックス」セルに値が含まれているかどうかを確認する必要があります。 「コンボボックス」セルに選択された値が含まれている場合、この値はUsedRacers
リストにも含まれます。このセルはUseRacers
リストにあるセルであるため、このセル項目リストにこの値を追加する必要があります。さもなければ、私たちはユニークな選択を表示することができません。
UsedRacers
のリストの一貫性を保つために、このアイテムを個々の「コンボボックス」セルに直接追加し、UsedRacers
リストを削除または変更しないでください。これは他の「コンボボックス」セルに使用されるためです。つまり、コンボボックスでどのような値が選択されていても、選択可能なアイテムの「コンボボックス」リスト内の項目の1つであることを確認する必要があります。私はそれが理にかなったことを願う
これは、すべて 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
(下記参照)の項目のコンボボックスリスト内の項目がUsedRacers
リストにあるすべての項目が含まれていないことをDataGridViewComboBoxCell
は、返します。このため、セルに値がすでに含まれているかどうかを確認するには、チェックが必要です(上記)。注:返されるDataGridViewComboBoxCell
には、常に空の空の項目が含まれます。これは、ユーザーが現在選択されている値を「De-Select」し、他のコンボボックスセルで「De-Selected」項目を使用できるようにするために必要です。
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考え方は、ユーザーがクリックしたコンボボックスに送信され、実行時にコンボボックスに移入できるということでした。 –