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

Vb.net 在WinForms中快速填充多个组合框的方法,vb.net,winforms,combobox,Vb.net,Winforms,Combobox,我正在VB.NET中使用.NET4.7.2开发一个Windows窗体应用程序。在选项卡控件的选项卡页面上,我有40个组合框控件,下拉样式为“DropDown”。当我进入选项卡时,我想查询数据库并获得结果。返回的字符串略多于5K。这个手术根本不需要花很多时间。然后,我希望所有组合框对可用项使用相同的列表、DataTable或BindingList。应允许每个组合框选择不同的值,而无需更新所有其他组合框。我试过的每一种方法都很慢。我试过List(字符串)、DataTable和BindingList(

我正在VB.NET中使用.NET4.7.2开发一个Windows窗体应用程序。在选项卡控件的选项卡页面上,我有40个组合框控件,下拉样式为“DropDown”。当我进入选项卡时,我想查询数据库并获得结果。返回的字符串略多于5K。这个手术根本不需要花很多时间。然后,我希望所有组合框对可用项使用相同的列表、DataTable或BindingList。应允许每个组合框选择不同的值,而无需更新所有其他组合框。我试过的每一种方法都很慢。我试过List(字符串)、DataTable和BindingList(字符串);其中,在设置数据源之前,我将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

有什么建议吗

您只需在选项卡页的控件上循环,并将每个组合框的数据源设置为
列表(字符串)


最后,我采纳了您的一些建议,并决定组合框可能不是存储超过5K个列表项的合适控件。相反,我将40个组合框切换为40个文本框。我将自动完成模式设置为“建议”,将自动完成源设置为“自定义源”。随着建议的调整,它真的像一个组合框,速度非常快,并做我需要它做的事情

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

我认为你无能为力。无论你做什么,用超过5000个项目填充40个组合框都需要时间。问题在于设计。组合框的设计并不是为了保持这样的项目数(更不用说同时保持40个)。考虑使用预加载的哈希集,然后使用组合框来动态搜索和填充。用户选择5000个项目中的哪一个有多容易?是否有某种方法可以减少这些组合框中的项目数?即使这意味着添加另一个组合框?@Mary您可以在参考源中看到它:当DisplayMember发生更改时,请遵循
RefreshItems()
方法,并在ListControl(组合框列表)中,遵循
SetDataConnection()
,在设置
DisplayMember
后调用。此属性定义列表元素的显示方式:如果更改,则需要重新生成列表以反映change@Mary是的,就是这样<代码>显示成员设置一个值,用于确定数据源中元素的显示方式。如果未设置属性,则实际上会显示列表项,调用
[Object].ToString()
,并以这种方式创建可见列表。如果更改
DisplayMember
值(可能指定属性或列名),则需要重置列表以生成新视图(除非
DisplayMember
值集与以前相同)。该过程仍然会很慢。另外,OP说他们已经尝试过使用
List(Of String)
@AhmedAbdelhameed,我认为这不会是一个缓慢的过程,因为你不是在将项目复制到
项目
集合,而是简单地将数据源属性分配给某个对象。它会的。你自己试试看。“但只需将datasource属性分配给某个对象”,这将导致更改
集合。请参阅我对上述问题的评论,以了解备选方案。
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