My apologies in advance for this rather long post.
I am working on a PDF viewer for Windows 8.1 Store apps. The viewer displays PDF pages inside a ScrollViewer. We've run into a fairly large obstacle with large documents, where it turns out that the ScrollViewer won't display anything below a certain VerticalOffset. There's a msdn thread about it here: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/f0b2b401-57ec-4cf0-9092-8bed5194f62b/scrollviewer-does-not-render-content-at-offsets-larger-than-2096700?forum=winappswithcsharp#4eb5d5c1-3887-4e3c-af03-96c0f6a8a7b2
Basically, if a document has some 1000 pages or so, then content below the offset 2096700 gets cut off. (We do offer a single page view mode with a FlipView, but that's an option for the user, not a solution to the problem).
As you can see in the thread, the suggestion is to virtualize the ScrollViewer.
As far as I am concerned, we already are vitualizing it. The ScrollViewer contains a Canvas of a size calculated to contain every page of the document, but it's completely transparent. Instead, as the user scrolls around, only the content where the viewport current is is rendered, as well as some of the surrounding content (in order to facilitate smooth scrolling). Content too far from the ViewPort is removed.
On a side note, this is how we originally built it for Windows 8.0, and it worked fine there. It's something that changed with the plumbing under the hood for Windows 8.1.
I've been thinking about how to solve this problem, and come up with a few possible solutions. However, I am not convinced they're the best ones available. So I wanted to ask others what they suggest I do.
One of the solutions I've thought of is to shrink the content of the ScrollViewer so that it's never larger than, say, 1000000. Then, when the user gets closer to the bottom of that, I can move back up to the top half and add all the content further up than it actually should be (basically, subtract 500000 from the offset). With zooming in and out, this might be somewhat tricky. The other problem now is of course the ScrollBars. I guess I would have to somehow add my own ScrollBars and make the ScrollViewer's two scrollbars invisible. Would this be doable?
Other than this, I can't relly think of anything else that could be considered virtualization. Perhaps some of you have an idea of how to solve a problem like this, or perhaps you could tell me that my above suggestion is crazy...
I also considered to leave the content of the ScrollViewer empty, and instead have my own content below (z level wise) that I can move about using RenderTransformations to match that of the ScrollViewer. I even ran a small experiment with colored rectangles, and found some issues which makes me thing it will be very hard to do. It seems that when the ScrollBar first pops up (Visibility auto) when you zoom in then the content jumps a bit. This might be solvable though...
I guess it's also possible to develop my own control from scratch... Maybe base it off of something like PanView (http://code.msdn.microsoft.com/windowsapps/PanView-A-Metro-Panning-dc8f28c3) I am however worried that the manipulation won't feel right (physics working differently than regular ScrollViewer). Also, the manipulation code will be executed on the UI thread, which might lead to some lag as it's already a rather heavy control.
Any other suggestions or ideas? I realize this is probably not a common problem.
Thanks, Tomas