【问题标题】:Custom caching for ListView with filtering具有过滤功能的 ListView 自定义缓存
【发布时间】:2015-09-17 21:26:51
【问题描述】:

我的 C# WPF 应用程序中有一个 ListView 和一个 GridViewItemsSource 绑定到在 ViewModel 上从 ObservableCollection<MyClass> 创建的 ListCollectionView。我使用ListCollectionView 进行动态排序、过滤和分组,所有这些都可以通过View 进行调整或打开/关闭。

当我更改过滤器或打开/关闭分组时,会重新创建所有可视列表视图项,这会导致 UI 冻结大约一秒钟。由于我显示了大约 250 个项目,并且大约有 10 列(其中一些具有带进度条的单元格模板),这不足为奇。

现在,我知道显而易见的答案是启用虚拟化。但是,这会带来一些不良影响,例如滚动变得生涩或滚动条在滚动时改变其大小(分组时会发生这种情况,因为组的高度不同,因此虚拟化堆栈面板无法正确计算总高度一开始)。

我想做的是让ListView 为原始列表中的每个项目保留一个视觉元素(未过滤和未排序,即ObservableCollection<MyClass>),然后仅添加到或从中删除可视化树取决于ListCollectionView 的变化。

我希望这个解决方案能够提高我的应用程序的性能,因为我很少更改原始列表,但我经常更改过滤、排序和分组。

我需要创建一个继承自ListView(或GridView)的自定义控件来执行此操作,还是有其他方法?

【问题讨论】:

  • 如果能附上一些代码就更好了,

标签: c# wpf listview listcollectionview


【解决方案1】:

尝试使用DeferRefresh,这会延迟自动刷新,直到存在延迟周期。看看有没有帮助。

CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(SomeListView.ItemsSource);
using (view.DeferRefresh())
{
  view.GroupDescriptions.Clear();
  view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
  view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
}

http://blogs.msdn.com/b/matt/archive/2008/08/28/collectionview-deferrefresh-my-new-best-friend.aspx

【讨论】:

  • 我已经对其进行了测试,它确实带来了轻微的加速,但我仍然觉得这并没有解决问题的核心——刷新时重新创建项目的所有视觉元素(即使只有一次)。
  • 作为 Jacob 的评论,您确实需要粘贴代码以进行进一步调查。我们的手在这里很紧。至少使用像 DotTrace 这样的分析器的快照会更多地暴露底层问题。
猜你喜欢
  • 2013-09-18
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
相关资源
最近更新 更多