开发者

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. 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.

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 l开发者_开发问答ock-up of a few seconds in the UI while it's torn down and recreated, and the ListBox repopulates. 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. 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. 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. 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? None of my attempts thus far have succeeded, seemingly because the ListCollectionView doesn't automatically marshal certain events on to the correct thread.

Pointers to or explanations of any known or potential solutions to these two issues would be very helpful.


Some interesting ideas in this SO thread about datagrid rendering and binding - you may be able to apply them to your listbox scenario as well...


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? Worth it.


2 tips from here, the first one might help for virtualizing the ListBox:

Virtualize lists and views by using a VirtualizingStackPanel as ItemsPanel for lists. 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!

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"

I did virtualization of my huge list of objects by the technique described here on codeproject, it works nicely

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜