简体   繁体   English

如何加快ListBox渲染和ListCollectionView过滤?

[英]How can I speed up ListBox rendering and ListCollectionView filtering?

A two-pronged question here, but I think these two subjects are entwined enough to warrant their inclusion together. 这里有一个双管齐下的问题,但我认为这两个主题交织在一起足以保证它们包含在一起。

In our application, we have a ListBox , which is populated with what might be a large number of items. 在我们的应用程序中,我们有一个ListBox ,其中填充了大量的项目。 Each of these items is displayed with a rather complicated item template. 这些项目中的每一项都显示有相当复杂的项目模板。 It's necessarily rather complicated, and while it could potentially be pared down a little more I probably couldn't take a huge amount out. 它必然相当复杂,虽然它可能会被削减一点,但我可能不会花费很多钱。 The items in the ListBox come from a ListCollectionView which is constructed from an ObservableCollection<> of the objects to display. ListBox的项来自ListCollectionView ,它是从要显示的对象的ObservableCollection<>构造的。

We have two problems. 我们有两个问题。

The first is that when we reconfigure filters for the ListCollectionView and call Refresh on it, there is a very noticable lock-up of a few seconds in the UI while it's torn down and recreated, and the ListBox repopulates. 第一个是当我们为ListCollectionView重新配置过滤器并在其上调用Refresh时,在UI被拆除并重新创建时,UI中存在非常明显的几秒钟锁定,并且ListBox重新填充。 The duration of this lock-up seems to be related to the number of elements contained in the ListBox , and is longest when the ListBox 's client area is full of items. 这种锁定的持续时间似乎与ListBox包含的元素数量有关,并且当ListBox的客户区域充满项目时,持续时间最长。 We're pretty certain that the lock-up is caused by the item templates being recreated. 我们非常肯定锁定是由重新创建的项目模板引起的。 I have tried turning on virtualization, but this had no effect in reducing or eliminating the slowdown. 我尝试过打开虚拟化,但这对减少或消除减速没有任何影响。 I'm also looking at some other optimizations, like examining our bindings and modifying the layouts. 我还在研究其他一些优化,比如检查我们的绑定和修改布局。 Is there any method for either avoiding this particular issue, speeding it up, or moving it to a different thread? 是否有任何方法可以避免这个特定问题,加快速度,或将其移动到不同的线程? (I know the last one's highly unlikely because the rendering is all single-threaded, but perhaps there's some workaround...) (我知道最后一个是不太可能的,因为渲染都是单线程的,但也许有一些解决方法...)

The second relates to the filtering on the ListCollectionView . 第二个涉及ListCollectionView上的过滤。 While it isn't an issue at present, we think that there's potential for the filtering to become an issue and cause a noticeable lock-up on the UI thread. 虽然目前这不是一个问题,但我们认为过滤有可能成为一个问题并导致UI线程明显锁定。 I am working to reduce the filtering overhead, but I was wondering if there's a method for moving the Refresh call on the ListCollectionView on to a different thread? 我正在努力减少过滤开销,但我想知道是否有一种方法将ListCollectionView上的Refresh调用移动到另一个线程? None of my attempts thus far have succeeded, seemingly because the ListCollectionView doesn't automatically marshal certain events on to the correct thread. 到目前为止,我的尝试都没有成功,似乎是因为ListCollectionView不会自动将某些事件ListCollectionView送到正确的线程上。

Pointers to or explanations of any known or potential solutions to these two issues would be very helpful. 指出或解释这两个问题的任何已知或潜在解决方案将非常有帮助。

在一些有趣的想法 SO线程有关数据网格渲染和有约束力的-你可以将它们应用到你的列表框的情况,以及...

I don't think you can virtualize AND filter at the same time. 我不认为你可以同时虚拟化和过滤。 So, if I were in your shoes, I'd stick with a virtualizing list box and do the filtering logic in another thread. 所以,如果我在你的鞋子里,我会坚持使用虚拟列表框并在另一个线程中执行过滤逻辑。 Sure, you might have to write some code that's already been written before, but if it doesn't lock up your GUI? 当然,您可能必须编写一些之前已经编写过的代码,但是如果它没有锁定您的GUI? Worth it. 值得。

2 tips from here , the first one might help for virtualizing the ListBox : 这里有 2个提示,第一个可能有助于虚拟化ListBox

Virtualize lists and views by using a VirtualizingStackPanel as ItemsPanel for lists. 通过将VirtualizingStackPanel用作列表的ItemsPanel来虚拟化列表和视图。 This only creates the visible elements at load time. 这仅在加载时创建可见元素。 All other elements are lazy created when they get visible. 所有其他元素在可见时都是惰性的。 Be aware that grouping or CanContentScroll="True" prevents virtualization! 请注意,分组或CanContentScroll="True"阻止虚拟化!

Enable Container Recycling. 启用容器回收。 Virtualization brings a lot of performance improvements, but the containers will be disposed and re created, this is the default. 虚拟化带来了许多性能改进,但容器将被处理并重新创建,这是默认设置。 But you can gain more performance by recycle containers by setting VirtualizingStackPanel.VirtualizationMode="Recycling" 但是,通过设置VirtualizingStackPanel.VirtualizationMode="Recycling"您可以通过回收容器获得更高的性能

I did virtualization of my huge list of objects by the technique described here on codeproject , it works nicely 我通过codeproject上描述的技术对我的巨大对象列表进行了虚拟化,它运行良好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM