2011-12-20 118 views
5

我想將項目添加到列表視圖控件。這是一段代碼:在ListView中添加項目太慢C#

this.lView.ListViewItemSorter = null; 
    ListViewItem[] lvitems = new ListViewItem[ListMyObjects.Count]; 
    int index = 0; 
    foreach (MyObject object in ListMyObjects) 
     { 
      ListViewItem item = new ListViewItem();    
      item.Text = object.Name; 
      lvitems[index++] = item; 
     } 
    this.lView.BeginUpdate(); 
    this.lView.Items.AddRange(lvitems); // Slow in here with debugger 
    this.lView.EndUpdate(); 

我只增加了約1000個項目,但它是非常緩慢的。花費大約15秒完成。 爲什麼有人知道原因?預先感謝。

編輯

我以前定製的列表視圖。

public partial class MyListView: ListView 
{   
    public MyListView() 
    { 
     InitializeComponent(); 
     this.View = View.Details; 
     this.FullRowSelect = true; 
     this.DoubleBuffered = true; 
    } 
    private bool mCreating; 
    private bool mReadOnly; 
    protected override void OnHandleCreated(EventArgs e) 
    { 
     mCreating = true; 
     base.OnHandleCreated(e); 
     mCreating = false; 
    } 
    public bool ReadOnly 
    { 
     get { return mReadOnly; } 
     set { mReadOnly = value; } 
    } 
    protected override void OnItemCheck(ItemCheckEventArgs e) 
    { 
     if (!mCreating && mReadOnly) e.NewValue = e.CurrentValue; 
     base.OnItemCheck(e); 
    } 
} 

我這樣做是因爲我不想在我使用多線程時掛起。我不知道這對它有什麼影響?

+1

哪一行是較慢的部分? (使用調試器) – SLaks 2011-12-20 03:39:16

+0

我認爲是這樣的...... – SLaks 2011-12-20 03:42:09

+1

我用整數值試過了,它以可接受的速度運行。 (<2秒)。也許它與你的對象有關? – Matthias 2011-12-20 03:42:34

回答

3

通過啓用virtual mode可以使其更快。
但是,這將需要一些工作。

+0

你知道什麼是那種行爲的原因?正如我對這個問題所評論的那樣,它對整數很有效。 – Matthias 2011-12-20 03:47:17

+0

@Slaks,強制垃圾收集器在foreach循環中運行。我認爲在GC自動運行之前內存中的對象太多了。您可能需要添加以下代碼行:GC.Collect(); GC.WaitForPendingFinalizers(); – 2011-12-20 03:59:16

+0

@BishnuPaudel:那根本不會有任何好處;循環中沒有任何東西要收集。 – SLaks 2011-12-20 16:12:18

3

添加多個項目的首選方法是使用AddRange() method。但是,如果您必須逐個添加項目,則可以在循環周圍使用BeginUpdate()和EndUpdate()方法。以下是來自MSDN

將多個項目添加到ListView的首選方法是使用ListView.ListViewItemCollection的AddRange方法(通過ListView的Items屬性進行訪問)。這使您可以通過單個操作將項目數組添加到列表中。但是,如果要使用ListView.ListViewItemCollection類的Add方法一次添加一個項目,則可以使用BeginUpdate方法防止控件在每次添加項目時重新繪製ListView。

0

適用於更多架構解決方案,但是如果您的域對象很大,這可能會導致瓶頸(讀取它的聲音聽起來像可能會減慢它)。在到達表示層之前,您可以將它們壓縮成一些(非常簡單的)域轉移對象(DTO):從字面上來說,它只是一羣getters-and-setters。

AutoMapper的工具可能會採取很多驢子的工作,在那裏

這樣,你的域對象停留在業務邏輯域(屬於他們的地方)和表示層剛剛從獲取需要的數據DTO。

對不起,對於非基於代碼的建議:)祝你好運!

+0

你能否解釋一下「大」對象與你的DTO(= [POCO's | http://en.wikipedia.org/wiki/Plain_Old_CLR_Object)有什麼不同?這些屬性只是一堆引用? – toong 2012-01-11 15:03:37

+0

Rant:所以評論系統沒有預覽,我需要收集更多的點才能編輯/修復我自己的評論? Yey .. – toong 2012-01-11 15:16:26

+0

DTO發送儘可能多的數據以支持依賴系統,而POCO也可能包含一堆其他數據。通常在系統內使用POCO,在兩個系統(系統是物理實體或邏輯系統)之間使用DTO。希望有所幫助,對不起評論系統給你的悲傷。 – 2012-01-11 23:27:20