![](/img/trans.png)
[英]Trying to Display the File name within a ComboBox.Items.AddRange()
[英]ComboBox.Items.AddRange Performance
我有一個ComboBox,當我重新填充它時,它似乎是一個非常耗時的任務。 在進行一些分析后,我發現大部分時間都花在了ComboBox.Items.AddRange(Array)方法上。 我在下面列出了一個示例方法,它顯示了我如何進行ComboBox的重新填充。
public void Repopulate(IList<MyType> sortedList)
{
MyComboBox.BeginUpdate();
try
{
MyComboBox.Items.Clear();
MyComboBox.Items.AddRange(sortedList.ToArray());
}
finally
{
MyComboBox.EndUpdate();
}
}
sortedList包含大約280個項目,最多需要重新填充53個ComboBox。 因此,重新填充所有這些控件可能需要相當長的時間(在高規格機器上約為700毫秒,在低規格機器上為8000毫秒),這對我的要求來說太慢了。 我嘗試將sortedList添加到一個新的IList,大約需要1ms(在我的高規格機器上)。
我需要重新填充ComboBox,以便花費更少的時間,理想情況下與IList相似,但任何性能提升都會很好。 到目前為止,我一直無法找到任何方法來提高重新人口的速度。
有沒有人知道如何減少重新填充ComboBox所需的時間?
您的問題可能是您啟用了組合框的Sorted
屬性。 啟用此功能並調用AddRange
,組合框AddRange
所有這些項目進行排序,如果您的項目已經排序,則不需要這些項目。
為了證明我的觀點,我創建了兩個使用10,000個排序的整數和AddRange
填充的組合框。 唯一的區別是一個組合框啟用了Sorted
屬性,另一個沒有。 以下是生成的AddRange
調用的時間(以毫秒為單位)
notSortedCombo: 5ms
sortedCombo: 1140ms
這可能是你的問題嗎? 你有53個組合框可以啟用排序屬性嗎?
AddRange
已經在引擎蓋下調用了BeginUpdate
和EndUpdate
,所以你自己調用它並沒有獲得任何東西。
這給我留下了幾毫秒的時間:
public void Repopulate(IList<string> sortedList) {
comboBox1.BeginUpdate();
comboBox1.Items.Clear();
foreach (string item in sortedList) {
comboBox1.Items.Add(item);
}
comboBox1.EndUpdate();
}
更大的問題可能是設計:53個組合框是向用戶投擲的很多組合框 - 用戶將無法同時與所有53個控件進行交互。 你可以得到一些hacky,只需用可見值(1項)填充組合框,然后在控件聚焦時或在后台計時器中填充列表。
但請考慮減少屏幕上的控件數量。 白色空間被認為是一件好事。
關於UI虛擬化:WPF( 示例 )和WinForms都存在虛擬化。 但只有一些控件支持它,如ListView,DataGridView,TreeView等。這些是為更大量的數據設計的控件。 如果可能,您可以切換到其中一個控件。
屏幕上是否同時顯示所有控件? 也許只更新可見的將有所幫助。
另一種方法是異步更新組合框。 如果你足夠幸運能夠在.NET中使用新的async / await東西,這很容易做到。 如果你想手動完成,你可以更新一個組合框,並在未來幾毫秒內安排下一個組合框的更新(使用計時器或TPL)。 這樣,在更新發生時,UI至少仍然響應。
另一種方法是僅在用戶關注某個ComboBox時更新列表。 通常不需要更新內容,因為用戶只能在使用ComboBox時看到它。
您還可以在更新其數據之前嘗試隱藏組合框。 或者您可以告訴Windows在修改內容時不重繪UI( 此處為StackOverflow主題 )。 但我還沒有測試這是否真的能提高性能。
您可以通過將組合框的FormattingEnabled
屬性更改為False
來提高性能
問題是,如果您未在設計器中“手動”指定項目,則Visual Studio會將其保持為True
,但會以編程方式添加它們。
試試吧,它解決了我的問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.