2009-02-24 50 views
3

我已經設置了一個包含多個選項卡的對話框。其中一個包括23個組合框,每超過100個項目,增加這樣的:顯示帶有很多ComboBox控件的選項卡與WinForms很慢

foreach (var x in collection) 
{ 
    string text = FormatItem (x); 
    combo.Items.Add (text); 
} 

所以沒有什麼花哨的所有項目。它們是純字符串,組合框在創建對話框時被填充。這幾乎是即時發生的。

但是,當用戶第一次單擊包含所有這些組合框的選項卡時,GUI會凍結幾秒鐘(並且我正在運行一臺非常健壯的機器)。

我加載了System.Windows.Forms的符號,並試圖在程序卡住時進入調試器。我發現是一個堆棧跟蹤與以下電話:

System.Windows.Forms.Control.CreateHandle() 
System.Windows.Forms.ComboBox.CreateHandle() 
System.Windows.Forms.Control.CreateControl(...) x 3 
System.Windows.Forms.Control.SetVisibleCore(true) 
System.Windows.Forms.TabPage.Visible.set(true) 

這將導致大量的原始過渡,WndProc調用等我想這種情況發生在每一個組合框的每一個項目。唷。

顯然,我無法優化WinForms。但是,也許我可以採取一些行動,以避免所有這一切在我的可憐的圖形用戶界面上失去?有任何想法嗎?

諾塔好處:

  1. 我已經把它貼在組合框時,你得到真正的創建控件可稱爲無事件處理程序。

  2. 如果我在創建並填充表單後嘗試訪問組合框的Handle屬性,那麼我在此時支付罰款,而不是當標籤第一次變爲可見時。但是在創建表單時不得不等待幾秒鐘也是不可接受的。我真的想擺脫很長的設定時間。

  3. 應用BeginUpdateEndUpdate的想法在這裏不適用:這些應該用於防止控件在其項目列表被填充時重新繪製。但就我而言,在控制設置完成後,問題發生得很好。

回答

1

我試過的一切都失敗了,現在加速了包含所有組合框的選項卡的第一個顯示。數據綁定也沒有幫助。

我終於決定通過做一個詭計來解決這個問題,類似於danbystrom提出的那樣,即當焦點首次到達組合時只填充Items集合。這仍然會產生明顯的延遲,即創建所有項目的時間(在BeginUpdateEndUpdate一對方法調用中),但它是可以容忍的(大約200ms,而在原始方案中爲幾秒)。

1

你說什麼是不是我觀察過任何一致...:■

但你有沒有嘗試過使用.BeginUpdate/.EndUpdate?

您嘗試的另一件事是而不是填充框直到需要。延遲它,直到框獲得焦點爲例...(如果你陷入下拉事件,一些用戶可能會惱怒,上/下箭頭鍵將無法正常工作。)

+0

是的,推遲填充控件的項目可以工作......但它需要相當多的調整,因爲我不能使用`SelectedIndex`和其他這樣的屬性。 – 2009-02-24 13:28:50

1

而不是迭代你的收藏,會設置ComboBox.DataSource是一個可行的,更快的選擇?

comboBox1.DataSource = myCollection1; 
comboBox2.DataSource = myCollection2; 
comboBox3.DataSource = myCollection3; 
// and so on... 

下面是一個更完整的示例:

public class Entity 
    { 
     public string Title { get; set; } 
     public override string ToString() 
     { 
      return Title; 
     } 
    } 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      List<Entity> list = new List<Entity> 
            { 
             new Entity {Title = "Item1"}, 
             new Entity {Title = "Item2"}, 
             new Entity {Title = "Item3"} 
            }; 

      comboBox1.DataSource = list; 

     } 
0

大量的控件的窗體上可能是一個問題。我曾經有過一個在50到100個文本框控件之間動態創建的表單。加載速度很慢。

我們通過改用datagrid來解決這個問題。這是一個針對大量數據進行優化的控件。我不知道你的具體要求是什麼,但它可能工作。

0

我剛剛遇到了這個問題,其中大約4000k項目的組合框填充速度令人難以接受。

我正在填充窗體的OnLoad事件處理程序的組合,但是,當我將這段代碼轉移到構造函數後,InitializeComponent()之後,根本沒有任何延遲。

我想在OnLoad中執行這個操作會導致組合重繪被觸發,因此延遲?無論如何,只是認爲我會添加這個以防在這種情況下對其他人有用。