【发布时间】:2010-11-06 08:27:10
【问题描述】:
我在后台线程上创建 ListViewItems 数组,然后在 ui 线程上用它填充我的列表视图。问题是如果数组太大,更新列表视图时 ui 会阻塞。
有没有办法在对 ui 影响很小的情况下填充列表视图?
【问题讨论】:
标签: c# listview user-interface controls
我在后台线程上创建 ListViewItems 数组,然后在 ui 线程上用它填充我的列表视图。问题是如果数组太大,更新列表视图时 ui 会阻塞。
有没有办法在对 ui 影响很小的情况下填充列表视图?
【问题讨论】:
标签: c# listview user-interface controls
如果您有大量数据进入,您可能希望在虚拟模式下使用它,方法是将 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 事件。
【讨论】:
您还可以使用 BeginUpdate 和 EndUPdate 方法
listView1.BeginUpdate();
//Add Values
listView1.EndUpdate();
【讨论】:
我的 cmets 已经很长了,所以我决定把这个单独发帖。
首先,Fredrik Mörk +1,使用 VirtualMode 是可行的方法。但是,您确实会失去一些功能,例如列自动调整大小,并且您自己更容易处理排序。
如果这是一个问题,从工作线程填充可能听起来很诱人。但是,填充仍将发生在拥有列表控件的线程中(即几乎总是主线程) - .NET 通过强制您使用(Begin)Invoke 使其可见。此外,如果您逐个填写,上下文切换将显着增加您需要填写所有项目的总时间,因此您想要填充块(例如一次 50 个项目,或者最好尽可能多地填充 20 个毫秒)。再加上内容更改时所需的额外同步,您有一个相当复杂的解决方案来解决不那么出色的结果。
【讨论】: