如何使用大量信息填充listview而不阻塞?

时间:2009-06-27 09:18:52

标签: c# listview user-interface controls

我在后台线程上创建一个ListViewItems数组,然后在ui线程上用它填充我的listview。问题是如果数组太大,ui会在列表视图更新时阻塞。

有没有办法填充列表视图,对ui产生很小的影响?

3 个答案:

答案 0 :(得分:8)

如果你有很多数据,你可能希望在虚拟模式下使用它,方法是将ListView控件的VirtualMode属性设置为true。这意味着ListView不会以传统意义填充,但是您将连接事件处理程序,您可以在显示项目时以小块的形式将信息传递到列表视图。

很简单的例子:

private List<string> _listViewData = new List<string>();
private void toolStripButton1_Click(object sender, EventArgs e)
{
    _listViewData = GetData(); // fetch the data that will show in the list view
    listView1.VirtualListSize = _listViewData.Count; // set the list size
}
// event handler for the RetrieveVirtualItem event
private void listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
    if (e.ItemIndex >= 0 && e.ItemIndex < _listViewData.Count)
    {
        e.Item = new ListViewItem(_listViewData[e.ItemIndex]);
    }
}

您还应该考虑使用CacheVirtualItems事件。

答案 1 :(得分:0)

您还可以使用BeginUpdate和EndUPdate方法

   listView1.BeginUpdate();
   //Add Values
   listView1.EndUpdate();

答案 2 :(得分:0)

我的评论很长,所以我决定把它作为一个单独的帖子。

首先,FredrikMörk的+1,使用VirtualMode是要走的路。但是,您确实失去了一些功能,例如列自动调整大小,排序更容易自己处理。

如果这是一个问题,从工作线程填充可能听起来很诱人。然而,群体仍将发生在拥有列表控件的线程中(即几乎总是主线程) - .NET通过强制使用(Begin)Invoke使其可见。此外,如果逐个填充,上下文切换将显着增加填充所有项目所需的总时间,因此您希望填充块(一次说50个项目,或者甚至更好地填充20个项目)毫秒)。除此之外,当内容发生变化时需要额外的同步,对于不那么出色的结果,你有一个非常复杂的解决方案。