在WinForms中填充多个组合框的快速方法

时间:2020-03-31 14:29:06

标签: vb.net winforms combobox

我正在使用.NET 4.7.2在VB.NET中开发Windows窗体应用程序。在选项卡控件的选项卡页面上,我有40个ComboBox控件,它们的DropDownStyle为“ DropDown”。当我进入选项卡时,我想查询数据库并获取结果。返回的字符串超过5K。此操作根本不需要很多时间。然后,我希望所有ComboBox都对可用项使用相同的List,DataTable或BindingList。应该允许每个组合框选择一个不同的值,而无需更新所有其他组合框。我尝试过的每种方法都非常慢。我已经尝试过List(Of String),DataTable和BindingList(Of String);在设置数据源之前,我将RaiseListChangeEvents设置为False。我还尝试在设置DataSource属性之前和之后将ComboBox的DisplayMember属性设置为“ Text”。没有一个可以加快这个过程。

这是我当前的代码:

    Private Sub RefreshBOXNComboBoxes()
    Dim lFibersMaster As List(Of String) = GetFISFiberIDs()
    For i As Integer = 1 To 40
        Dim strControlName As String = "cboBOXN_Slot_" & i.ToString().PadLeft(2, "0")
        Dim objCombo As ComboBox = DirectCast(tpBOXN.Controls(strControlName), ComboBox)
        Dim blFibers As New BindingList(Of String)(lFibersMaster)
        blFibers.RaiseListChangedEvents = False
        With objCombo
            .DataSource = blFibers
            .DisplayMember = "Text"
            .SelectedIndex = -1
        End With
    Next
End Sub
Private Function GetFISFiberIDs() As List(Of String)
    Dim ret As New List(Of String)()
    Dim strConnectionString = ConfigurationManager.ConnectionStrings("FIS").ConnectionString
    Using conFIS As New OracleConnection(strConnectionString)
        conFIS.Open()

        Dim strSQL = "SELECT DISTINCT SERIAL_FIBER_ID FROM FIS.FIB_DATA_HEADER ORDER BY SERIAL_FIBER_ID"
        Using cmdFIS As New OracleCommand(strSQL, conFIS)
            Using drFIS As OracleDataReader = cmdFIS.ExecuteReader()
                While drFIS.Read()
                    ret.Add(drFIS("SERIAL_FIBER_ID").ToString())
                End While
            End Using
        End Using
        conFIS.Close()
    End Using
    Return ret
End Function

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您可以简单地遍历TabPage的控件并将每个ComboBox的数据源设置为List(Of String)

Private Sub RefreshBOXNComboBoxes()
    Dim lFibersMaster As List(Of String) = GetFISFiberIDs()
    For Each cb As ComboBox In TabPage1.Controls().OfType(Of ComboBox)
        cb.DataSource = lFibersMaster
    Next
End Sub

答案 1 :(得分:0)

我最终接受了您的一些建议,并确定ComboBox可能不是用于存储5K以上ListItems的正确控件。相反,我将40个ComboBoxes切换为40个TextBoxes。我将全部40个AutoCompleteMode设置为“ Suggest”,将AutoCompleteSource设置为“ Custom Source”。启用“建议”功能后​​,它的作用就像一个ComboBox,速度非常快,并且可以完成我需要做的事情。

Public colFISFibers As AutoCompleteStringCollection
Private Sub RefreshBOXNFISFiberControls()
    Dim lFibersMaster As List(Of String) = GetFISFiberIDs()
    colFISFibers = New AutoCompleteStringCollection()
    colFISFibers.AddRange(lFibersMaster.ToArray())

    For i As Integer = 1 To 40
        Dim strControlName As String = "txtBOXN_Slot_" & i.ToString().PadLeft(2, "0")
        Dim objTextBox As TextBox = DirectCast(tpBOXN.Controls(strControlName), TextBox)
        With objTextBox
            .AutoCompleteCustomSource = colFISFibers
            .Text = String.Empty
        End With
    Next
End Sub
Private Function GetFISFiberIDs() As List(Of String)
    Dim ret As New List(Of String)()
    Dim strConnectionString = ConfigurationManager.ConnectionStrings("FIS").ConnectionString
    Using conFIS As New OracleConnection(strConnectionString)
        conFIS.Open()

        Dim strSQL = "SELECT DISTINCT SERIAL_FIBER_ID FROM FIS.FIB_DATA_HEADER ORDER BY SERIAL_FIBER_ID"
        Using cmdFIS As New OracleCommand(strSQL, conFIS)
            Using drFIS As OracleDataReader = cmdFIS.ExecuteReader()
                While drFIS.Read()
                    ret.Add(drFIS("SERIAL_FIBER_ID").ToString())
                End While
            End Using
        End Using
        conFIS.Close()
    End Using
    Return ret
End Function