Making a Virtualizing WrapPanel

Gotchas and Pain Points

Congratulations, you’ve written a virtualizing WrapPanel! Now for some bad news, virtualization won’t work in some scenarios.

To be specific, if you use your panel inside a ListBox and turn grouping on, virtualization is broken. To understand why, use Snoop to look at your visual tree. When using grouping in a ListBox, your ItemsPanel is implicitly wrapped inside a StackPanel that is the direct child of the ListBox’s ScrollViewer. Because this happens, the ScrollViewer doesn’t “see” your panel, so it’s ScrollOwner is not set. In turn, your panel receives infinite bounds for the viewport in MeasureOverride.

Unfortunately, I haven’t implemented a solution, but a possible one would be to write a custom panel for the grouping that communicates with your inner panel so that it does receive a proper viewport size.

That’s it. Although the past two months have been painful, I have learned a lot about how to write virtualizing panels (more than I ever wanted to), and hopefully I’ve taught you a lot in turn. It’s my firm hope/wish that Microsoft provides better documentation and best practices for this aspect of WPF, or even better – providing us with virtualizing counterparts to all the standard panels that ship with WPF.

EDIT 2/11/2008: I’ve spent the last few days trying to get my VirtualWrapPanel to perform virtualization with grouping turned on inside a ListBox. To be really blunt, it’s been a pain in the ass thus far. Ben Carter, a member of the WPF development team e-mailed me a technique to get around this, but it involves implementing a virtualizing panel for the ListBox’s GroupingPanel. I’ll post an update if I ever get this to work..

Explore posts in the same categories: WPF

Pages: 1 2 3 4

Tags: , , , ,

You can comment below, or link to this permanent URL from your own site.

5 Comments on “Making a Virtualizing WrapPanel”


  1. [...] from a major software company about Virtualizing WrapPanel…looks like Jerry did that too: "Making a Virtualizing WrapPanel".  (no code, but he helps explain more about how to do [...]

  2. laduran Says:

    Jerry,

    Thanks for writing this! This is a really good article and will help me implement what I need. I need to create a StackPanel (could be a wrap panel) that will implement scrolling in a different way than normal. Our designer thought it would be a good idea if our program didn’t have any scroll bars. Luckily we don’t have lots of data that needs to be shown in any given stack panel … Just more controls.

    Stack panels that have more content than can fit into the scroll viewer will have buttons at the top and bottom. If the user wishes to scroll down, they hit a “Page Down” button. This will cause all the elements in the current view that are visible to fade out, then the elements that are under the last fully visible element will slide up into view. The opposite will occur if the user tries to page up.

    I don’t need to worry about virtualizing visuals since the number of child controls in my panel will be always be small (under 10). The one concern I have is that I will be able to perform two different Animations in the ArrangeOverride function. Maybe I just need to fade the visible items out in the IScrollInfo.PageDown function and then translate the items into view in the ArrangeOverride function.

    My biggest concern is being able to determine what child controls are visible in the scrollviewer and which are not. Is there an easy way to determine this?

    Thanks,
    Louis

  3. jweizman Says:

    Hi Jerry

    I’m trying to implement such a panel using your advices.

    I have a question:
    *If you do not clean the items after you scroll, then the more your scroll the more memory to consume ? Isn’t it ?

    Thanks
    Jonathan

    • Jerry Lin Says:

      Hi Jonathan,

      Right, the panel will keep consuming memory until you’ve loaded all your items into it. I admit it’s not the ideal way to do things, yet at the time of this article, the items I were loading were from disk, and wanted to avoid having to constantly read from the hard drive from loading and unloading the items. After I wrote the article, I was assigned to other areas of my project not having to do with WPF, so it’s with regret that I haven’t had the chance to explore a possible better solution.

      Fortunately, we had a major release last week, so I now have some free time. Thanks for asking, I will try to explore better solutions and get them posted if I find any :-)

      Jerry

  4. renovatio1510 Says:

    I followed the Dan guide for the virtualization. I started implementing an uniform grid (tile panel). Anyway i’m not able to calculate the extent, cause the set of children of the panel is dynamically changed by the panel itself, who asks the ItemContainerGenerator to build/dispose the containers. At every moment, the set of children of the panel contains only (the containers for) the realized items (right?)

    Anyway, to calculate the size of the extent (to enable scrolling) the panel should know the total number of the items (realized and virtualized).

    Any help?


Comment:

You must be logged in to post a comment.