2017-05-26 9 views
0

私はtabcontrolにタブを作成し、DataGridViewComboBoxColumnである2つの列を含むdatagridviewでそのコードを埋め込むコードの一部を持っています。VB.NETプログラムで作成されたコントロールにあるComboBoxColumnにイベントハンドラを追加する方法は?

それは次のようになります。

Private Sub NewTabPage() 
    Dim TabPageCount As Integer = RacerOrderTAB.TabPages.Count 
    RacerOrderTAB.TabPages.Add(TeamNames(TabPageCount)) 'teamnames() is an array of team names 

    Dim CurrentTabPage = RacerOrderTAB.TabPages(TabPageCount) 
    Dim GridToAdd As New DataGridView 

    GridToAdd.Size = CurrentTabPage.Size 
    GridToAdd.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill 
    GridToAdd.Location = New Point(CurrentTabPage.Location.X, CurrentTabPage.Location.Y) 
    GridToAdd.Columns.Add("ShiftCOL", "Shift Name") 
    GridToAdd.Name = "grid_" & CurrentTabPage.Text 

    For y As Integer = 1 To ShiftSetup.racerspershift 'add extra column for each racer in shift 

     Dim cmb As New DataGridViewComboBoxColumn 

     cmb.HeaderText = "Racer" & y 
     cmb.Name = "Racer_" & y 
     cmb.MaxDropDownItems = AmountOfRacers 
     cmb.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton 

     GridToAdd.Columns.Add(cmb) 
    Next 

    RacerOrderTAB.TabPages(TabPageCount).Controls.Add(GridToAdd) 
End Sub 

しかし、私はコンボボックスのためのイベントハンドラを追加することの難しさを持ってきました。私がしたいのは、コンボボックスをクリックして開くときに、私が望むアイテムでコンボボックスを作成するということです。 私は漠然とそれが追加することによって、作業を取得するために管理:

AddHandler GridToAdd.EditingControlShowing, AddressOf <sub name> 

が、その後は、クリックされたコンボボックスを把握できていない、とどのようにそれを移入します。また、ドロップリストが表示されるまでに4回のクリックが必要です。私はわずかに非常に混乱しています。

アドバイスありがとうございます。これらのDataGridViewComboBoxColumns [深呼吸]は私を多く混乱させています!

+0

通常、列には「ComboBox」コントロールはありません。複数のコントロールはありません。したがって、クリックされたコントロールを決める必要はありません。 'EditingControlShowing'イベントハンドラでは、唯一の' ComboBox'は 'e.Control'プロパティを介してアクセスできます。 – jmcilhinney

+0

コンボボックスに含める内容が不明です。投稿されたコードは多数のコンボボックスの列を作成するように見えますが、コンボボックスに項目を追加する投稿コードには何もありません。コンボボックスに含めるものを明確にすることはできますか?それらはすべて同じ値を持つか、それぞれが独自の値を持ちますが、コードはどちらも行いません。 – JohnG

+0

@ JohnG考え方は、ユーザーがクリックしたコンボボックスに送信され、実行時にコンボボックスに移入できるということでした。 –

答えて

1

少しハッキリかもしれませんが、うまくいけばいいと思います。私は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 

私は、これは私がこれを行うための簡単な方法があります推測しています、助けを願っています。

関連する問題