Recycling that Item Container

Item container recycling is a one of the many new features in SP1.  I’m going to talk a little bit about it here.

What is it?

As a little background, the VirtualizingStackPanel’s virtualization scheme basically works like this: generate containers when needed and throw them away when they are no longer in view.  This does solve the memory issue that is created when the panel has a large number of items, but it can still be very expensive to have to recreate and throw away containers every time they go out of view.  Enter container recycling.  Container recycling is a performance optimization to this virtualization scheme.  It basically reuses existing containers so they do not have to be recreated each time they come back into view.

How do I use it?
VirtualizingStackPanel’s virtualization will still work the same as before.  In fact container recycling will be turned off by default.  I will explain how to turn it on shortly, but before that let me describe the new API.  VSP (VirtualizingStackPanel) has added a new attached property, VirtualizationModeProperty, as well as the getter and setter for it, GetVirtualizationMode and SetVirtualizationMode.  This property is used to describe the type of mode that it can be in, VirtualizationMode.Standard or VirtualizationMode.Recycling.  The former will use the standard virtualization scheme just as it normally would and the latter will include recycling to the virtualization scheme.  The VirtualizationModeProperty is to be set from the ItemsControl that hosts the items presented by the VSP.  By default, it is set to VirtualizationMode.Standard.

Here is an example of turning on recycling on a ListBox:

<ListBox VirtualizingStackPanel.VirtualizationMode=”Recycling” …/>

Note that ListBox uses a VSP as its ItemsPanel and sets the VirtualizingStackPanel.IsVirtualizing attached property to true by default.  If you were using ItemsControl directly or creating a custom ItemsControl that uses a VSP as its ItemsPanel, you will need to set both attached properties to get the recycling behavior.

<ItemsControl VirtualizingStackPanel.IsVirtualizing=”true” VirtualizingStackPanel.VirtualizationMode=”Recycling” …/>

Special considerations

Just as with the virtualization scheme, marking containers as non-virtualizable will not virtualize or recycle the container.  You can do this by handling VSP’s CleanUpVirtualizedItem event.  This event is fired when a container is about to be thrown away or recycled.  You have the option here of cancelling the operation. 

Some other helpful methods for you to have more control of the data items and containers include ItemsControl.PrepareContainerForItemOverride which is called before a container is used and ItemsControl.ClearContainerForItemOverride which is called when a container is thrown away or recycled.

For more information regarding scrolling performance take a look at this article by one our dev’s here on the WPF team.  It came out before this feature so the information regarding container recycling is a suggestion on how to implement it and not how to actually use it.  It still has a lot of great information though.


Comments (9)

  1. Rudi Grobler says:

    With the beta release of .NET 3.5 SP1, scrolling received some much needed performance increases! Lets

  2. So far for the new WPF 3.5 SP1 features, I’ve surveyed Item Container Recycling , Data Formatting , and

  3. shunchen says:


    While i use the listview in WPF, I found a urgent question. I know that it has implemented the UI virtualization in listview, so it can throw away containers every time they go out of view. But i want to know what it mean exactly about "throw away". By my test, it seems the memory are always occupied, not released. For example, i add 1000+ items into listview, then it will take up a large number of memory while i scrolling. The most important is that the memory can’t be released automatically, except closing the application.

    What can i do about the issue?


  4. Virtualization from the VirtualizingStackPanel’s point of view means that memory is allocated for the panel’s item containers that are in view.  When they go out of view they are "thrown away" meaning they will be set to be garbage collected (whenever that will be which is set by the garbage collector).  I’m not exactly sure how you are testing the memory footprint of your app from what you are saying so I can’t really make any conclusions from it.  Also, it’s a managed app so you only have so much control of the garbage collector.  Do you also have item container recycling turned on?  I just did a really quick and dirty test with an app that I’m current developing and added a ListView with 100 items and item container recycling turn on and off.  With it off the memory footprint of my app was between 132MB – 135MB.  When I turned it back on it was between 77MB – 84MB.  So one thing that you can do and get for free is turn on item container recycling (if you haven’t done so).

    Also, if you do want to see the performance impact, try turning off virtualization and then try scrolling.  I accidentally ran into this issue the other day as I forgot that when you add grouping, virtualization is automatically turned off.  I had around 4000 items which is relatively not that many and my app was slowed down to a crawl.  

  5. Shunchen says:

    Hi, vinsibal

    Thanks for your help firstly. I tried that new property VirtualizationMode="Recycling" in SP1. The result is perfect that the memory usage is cut.

    However, i found another urgent issue while i updated to SP1. If VirtualizationMode is set with "Recycling", I tried to clear the collection (which binding to the listview’s itemssource) and fill it with new items. Then it will throw exception if invoking the ScrollIntoView() of listbox.

    >> It can work well with .net 3.5(no sp1)

    >> It can work well if VirtualizationMode isn’t set with "Recycling"

    >> It can work well if removing items in collection (which binding to itemssource) one by one instead of clearing it. I means that to call RemoveAt() instead of Clear() .

  6. Thanks for all the information.  I was able to repro exactly.  After some investigation, we found this is a bug in the recycling code.  It has been logged and will be addressed in our future release.  

    Right now it seems that the RemoveAt function is the easiest workaround right now but I will look into this a bit more to see if there is a more intuitive work around.  Thanks again for your commetns!

  7. .NET 3.5 SP1 buzz peaked very early at the beta.&#160; At the time I was immersed in Silverlight, so

  8. Luke says:

    Any news on when Virtualization support will be supported when grouping within the ListView is enabled?

  9. Luke,

    It is on the list of features for future releases but we do not have any solid dates for when that will be supported.  In the meantime you can make use of the workaround that I have a link for here,