【问题标题】:How to populate listview with a lot of information without blocking?如何在不阻塞的情况下用大量信息填充列表视图?
【发布时间】:2010-11-06 08:27:10
【问题描述】:

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

有没有办法在对 ui 影响很小的情况下填充列表视图?

【问题讨论】:

    标签: c# listview user-interface controls


    【解决方案1】:

    如果您有大量数据进入,您可能希望在虚拟模式下使用它,方法是将 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 事件。

    【讨论】:

      【解决方案2】:

      您还可以使用 BeginUpdate 和 EndUPdate 方法

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

      【讨论】:

        【解决方案3】:

        我的 cmets 已经很长了,所以我决定把这个单独发帖。

        首先,Fredrik Mörk +1,使用 VirtualMode 是可行的方法。但是,您确实会失去一些功能,例如列自动调整大小,并且您自己更容易处理排序。

        如果这是一个问题,从工作线程填充可能听起来很诱人。但是,填充仍将发生在拥有列表控件的线程中(即几乎总是主线程) - .NET 通过强制您使用(Begin)Invoke 使其可见。此外,如果您逐个填写,上下文切换将显着增加您需要填写所有项目的总时间,因此您想要填充块(例如一次 50 个项目,或者最好尽可能多地填充 20 个毫秒)。再加上内容更改时所需的额外同步,您有一个相当复杂的解决方案来解决不那么出色的结果。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-09
          • 1970-01-01
          • 1970-01-01
          • 2019-09-12
          • 1970-01-01
          相关资源
          最近更新 更多