【问题标题】:How to efficiently filter a large LIstViewItemCollection?如何有效过滤大型 LIstViewItemCollection?
【发布时间】:2010-09-15 05:36:46
【问题描述】:

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

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

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

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

我在使用这样的大样本从 .NET 控件中寻求性能方面不是很有经验,所以我真的不知道更好的方法来做到这一点。有没有办法使用 .Add() 方法,或者如果没有,只是更好的通用解决方案?

【问题讨论】:

    标签: c# .net winforms performance listview


    【解决方案1】:

    还有更好的办法,可以使用列表视图的VirtualMode

    该文档应该可以帮助您入门。这个想法是仅在需要时向 ListView 提供信息。使用事件检索此类信息。您所要做的就是实现这些事件并告诉列表视图它包含多少项。

    【讨论】:

    • 这确实提供了更好的性能,但可以做更多的工作。我怀疑只有几百个列表,在修改列表时禁用排序会更容易。
    • 我不会认为它需要更多的工作 - 只是更多的工作。当然,微软的例子让它看起来很多,但它们总是那样荒谬。 :-)
    • 好吧,这没什么好争论的。 :D
    【解决方案2】:

    AddRange 比 add 快得多

    MyListView.AddRange(items)
    

    【讨论】:

      【解决方案3】:

      解决这个问题有两点:

      1. 在处理列表内容时关闭排序。
      2. 隐藏列表,使其不会尝试绘制。

      第一点是这两者中列表操作的最大性能提升。为此,只需在修改期间将 ListViewItemSorter 设置为 null 并在最后将其设置回来。

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

      【讨论】:

        【解决方案4】:

        还请注意,您可以隐藏项目,从而使它们不可见,而无需删除它们。因此,第一次添加所有项目,然后您只需隐藏不再需要的项目并显示那些不再需要的项目。

        【讨论】:

        • 其实我乍一看并没有找到适合的属性。我会看起来更努力。
        • 我认为这是不可能的,除非您所有者绘制列表视图。
        猜你喜欢
        • 2012-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-29
        • 1970-01-01
        • 1970-01-01
        • 2020-10-25
        • 2022-10-01
        相关资源
        最近更新 更多