This topic has plagued me for some time now and I finally was able to engineer a working solution to achieve my goal. The challenge was to be able to display a series of items each containing a header and an variable number of child items. By itself, this is a fairly trivial problem to overcome, however, I had a few additional constraints that change the nature of the problem completely.
Constraint #1: Instead of scrolling, the layout must display whatever possible in the available height, and the remaining items should appear on subsequent pages.
Constraint #2: Each item will consist of a header and a variable number of sub items. If there is no remaining space to display sub items on the current page, the items should appear on the next page, along with the appropriate header.
Constraint #3: If the available screen height changes, the layout should adjust to display as many items and sub items as possible.
Constraint #4: If there is no room to show any sub items after displaying the header on the current page, then don’t display the header at all.
The illustration below should help you visualize how the paging should work:
Trials and Dead-Ends
Has this path been travelled? It is likely that someone else has indeed run into the same problem and blogged their experiences, so I search and discover something close, a Paging Wrap Panel in WPF. This example is very similar to my requirements, only it assumes that all items are the same height. In my scenario, the items (including sub items) are variable height and I need to repeat headers when all of the sub items don’t fit on a page. Cue the Sad Trombone.
What does the StackOverflow crowd think? I posted a question and got a few responses, but nothing like I had hoped.
Originally, I had planned to iteratively add an item and check the height after each item. If the item did not fit in the available space, I would suspend rendering items until the layout was moved to the next page. My main issue was that I could not determine the height of an item until after it had been rendered.
After many failed attempts, I was starting to lose hope, but I eventually discovered that I could add all of the items in one iteration and then cycle back through and hide items until the appropriate set was being displayed (with respect to the current page).
So, I’ve included a live demo that you can try out and the source code is available as well. This isn’t my final version of the code. I ended up refactoring, generalizing, and re-packaging this as a reusable control for my own uses. I don’t plan on releasing the final version, but this should get you started if you have the same problem. Enjoy!
Download Source Code
Live Demo
