2017-05-26 66 views
0

我有我的代碼的一部分,在tabcontrol中創建一個選項卡,然後用包含DataGridViewComboBoxColumn幾個列的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> 

但隨後一直無法找出點擊了哪個組合框,以及如何來填充它。在下拉列表出現之前,它也需要四次點擊。我只是有點困惑。

感謝您的任何建議;這些DataGridViewComboBoxColumns [深呼吸]一直讓我困惑不已!

+0

列中通常沒有'ComboBox'控件,並且從不超過一個,因此從不需要確定哪個被點擊。在EditingControlShowing事件處理程序中,唯一的'ComboBox'可以通過'e.Control'屬性訪問。 – jmcilhinney

+0

目前還不清楚你想要組合框包含什麼。發佈的代碼似乎會生成許多組合框列,但是發佈的代碼中沒有任何內容將項目添加到這些組合框。你能澄清你想要組合框包含什麼嗎?它們都具有相同的值,或者每個都有自己的值,但代碼都不具備。 – JohnG

+0

@JohnG想法是,我將被髮送到用戶點擊的任何組合框,然後我可以在運行時填充它。 –

回答

1

它可能有點不好意思,但它應該做你在問什麼...希望。我創建了兩個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列表一致,我們需要直接將此項添加到單個「組合框」單元中,而不是刪除或更改列表,因爲這將用於其他「組合框」單元。換句話說,無論在組合框中選擇了什麼值,我們都需要確保它是「組合框」可選項列表中的項目之一。我希望這是有道理的。

這可以全部在DataGridViewsCellChanged事件中完成。

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 

我希望這可以幫助,我猜還有一個更簡單的方法來做到這一點。

相關問題