如何有效地过滤大型LIstViewItemCollection?

时间:2021-07-11 21:25:57

So I have a ListView with an upper limit of about 1000 items. I need to be able to filter these items using a textbox's TextChanged event. I have some code that works well for a smaller number of items (~400), but when I need to re-display a full list of all 1000 items, it takes about 4 seconds.

所以我有一个ListView,其上限约为1000项。我需要能够使用文本框的TextChanged事件过滤这些项目。我有一些代码适用于较少数量的项目(约400),但是当我需要重新显示所有1000个项目的完整列表时,大约需要4秒钟。

I am not creating new ListViewItems every time. Instead, I keep a list of the full item collection and then add from that. It seems that the .Add method is taking a long time regardless. Here is a little sample:

我不是每次都创建新的ListViewItems。相反,我保留了完整项目集合的列表,然后从中添加。无论如何,.Add方法似乎需要很长时间。这是一个小样本:

this.BeginUpdate();
foreach (ListViewItem item in m_cachedItems)
{
    MyListView.Add(item);
}
this.EndUpdate;

I have tried only adding the missing items (i.e., the difference between the items currently being displayed and the total list of items), but this doesn't work either. There can be a situation in which there is only one item currently displayed, the user clears the textbox, and I need to display the entire list.

我尝试过只添加缺失的项目(即当前显示的项目与项目总列表之间的差异),但这也不起作用。可能存在当前只显示一个项目的情况,用户清除文本框,我需要显示整个列表。

I am not very experienced in eeking performance out of .NET controls with a large sample like this, so I don't really know a better way to do it. Is there any way around using the .Add() method, or if not, just e better general solution?

我对使用像这样的大样本的.NET控件的性能不是很有经验,所以我真的不知道更好的方法。有没有办法使用.Add()方法,或者如果没有,只是更好的通用解决方案?

4 个解决方案

#1


2  

There are two things to address this:

有两件事要解决这个问题:

  1. Turn off sorting while manipulating the list contents.
  2. 在操作列表内容时关闭排序。

  3. Hide the list so it doesn't try to paint.
  4. 隐藏列表,使其不会尝试绘制。

The 1st point is the biggest performance gain in list manipulation out of these two. To achieve this, just set the ListViewItemSorter to null for the duration of the modification and set it back at the end.

第一点是这两个列表操作中最大的性能提升。要实现此目的,只需在修改期间将ListViewItemSorter设置为null,并在结束时将其设置为null。

For the 2nd option, I often draw the list to a bitmap and then show that bitmap in a PictureBox so the user doesn't see the list disappear, then just reshow the list when I'm done.

对于第二个选项,我经常将列表绘制到位图,然后在PictureBox中显示该位图,以便用户看不到列表消失,然后在完成后重新显示列表。

#2


4  

There is a better way, you can use the VirtualMode of the list view.

有一种更好的方法,您可以使用列表视图的VirtualMode。

That documentation should get you started. The idea is to provide information to the ListView only as it's needed. Such information is retrieved using events. All you have to do is implement those events and tell the list view how many items it contains.

该文档应该让你开始。我们的想法是仅在需要时向ListView提供信息。使用事件检索此类信息。您所要做的就是实现这些事件并告诉列表视图它包含多少项。

#3


3  

AddRange is much faster than add

AddRange比添加快得多

MyListView.AddRange(items)

#4


0  

Also note that you can hide items and so make them invisible without removing them. So add all your items the first time around and then later on you just hide the ones no longer needed and show the ones that are.

另请注意,您可以隐藏项目,以便在不删除它们的情况下使其隐藏。因此,第一次添加所有项目,然后稍后您只需隐藏不再需要的项目并显示那些项目。

#1


2  

There are two things to address this:

有两件事要解决这个问题:

  1. Turn off sorting while manipulating the list contents.
  2. 在操作列表内容时关闭排序。

  3. Hide the list so it doesn't try to paint.
  4. 隐藏列表,使其不会尝试绘制。

The 1st point is the biggest performance gain in list manipulation out of these two. To achieve this, just set the ListViewItemSorter to null for the duration of the modification and set it back at the end.

第一点是这两个列表操作中最大的性能提升。要实现此目的,只需在修改期间将ListViewItemSorter设置为null,并在结束时将其设置为null。

For the 2nd option, I often draw the list to a bitmap and then show that bitmap in a PictureBox so the user doesn't see the list disappear, then just reshow the list when I'm done.

对于第二个选项,我经常将列表绘制到位图,然后在PictureBox中显示该位图,以便用户看不到列表消失,然后在完成后重新显示列表。

#2


4  

There is a better way, you can use the VirtualMode of the list view.

有一种更好的方法,您可以使用列表视图的VirtualMode。

That documentation should get you started. The idea is to provide information to the ListView only as it's needed. Such information is retrieved using events. All you have to do is implement those events and tell the list view how many items it contains.

该文档应该让你开始。我们的想法是仅在需要时向ListView提供信息。使用事件检索此类信息。您所要做的就是实现这些事件并告诉列表视图它包含多少项。

#3


3  

AddRange is much faster than add

AddRange比添加快得多

MyListView.AddRange(items)

#4


0  

Also note that you can hide items and so make them invisible without removing them. So add all your items the first time around and then later on you just hide the ones no longer needed and show the ones that are.

另请注意,您可以隐藏项目,以便在不删除它们的情况下使其隐藏。因此,第一次添加所有项目,然后稍后您只需隐藏不再需要的项目并显示那些项目。