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