2011-12-20 145 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