问题描述
我为这篇相当长的帖子提前道歉。
我正在为Windows 8.1 Store应用程序开发PDF查看器。查看器在ScrollViewer中显示PDF页面。我们遇到了大型文档的一个相当大的障碍,事实证明ScrollViewer不会显示任何低于某个
VerticalOffset的内容。这里有一个关于它的msdn帖子: 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
我虽然最好开始一个新线程,因为我已经接受了我将不得不自己做点什么。
基本上,如果文档大约有1000页左右,则偏移2096700以下的内容会被切断。 (我们提供带有FlipView的单页面查看模式,但这是用户的选项,而不是问题的解决方案。)
正如您在线程,建议是虚拟化ScrollViewer。
就我而言,我们已经在虚拟化它。 ScrollViewer包含一个Canvas,其大小经过计算,可以包含文档的每个页面,但它完全透明。相反,当用户滚动时,仅呈现视口当前为
的内容,以及一些周围内容(以便于平滑滚动)。删除了远离ViewPort的内容。
在旁注中,这就是我们最初为Windows 8.0构建它的方式,它在那里工作得很好。随着Windows 8.1引擎盖下的管道发生了变化。
我一直在考虑如何解决这个问题,并提出一些可能的解决方案。但是,我不相信它们是最好的。所以我想问别人他们建议我做什么。
我想到的一个解决方案是缩小ScrollViewer的内容,使其永远不会超过比方说,1000000。然后,当用户接近底部时,我可以回到上半部分,并将所有内容进一步加上
比实际应该更多(基本上,从中减去500000)偏移)。随着放大和缩小,这可能有点棘手。另一个问题现在当然是ScrollBars。我想我必须以某种方式添加我自己的ScrollBars并使ScrollViewer的
两个滚动条不可见。这是否可行?
除此之外,我不能再考虑任何可以被视为虚拟化的东西了。也许你们中的一些人知道如何解决这样的问题,或者你可能会告诉我,我的上述建议很疯狂......
我也考虑过将ScrollViewer的内容留空,而是在下面(z级别)使用我自己的内容,我可以使用RenderTransformations来匹配ScrollViewer的内容。我甚至用彩色的
矩形进行了一个小实验,发现一些问题让我觉得很难做到。看来,当你放大ScrollBar首次弹出(Visibility auto)时,内容会跳跃一点。这可能是可以解决的......
我想也可以从头开发我自己的控件...也许基于像PanView这样的东西( http://code.msdn.microsoft.com/windowsapps/PanView-A-Metro-Panning-dc8f28c3 )
但我担心操作感觉不对(物理工作与常规ScrollViewer不同)。此外,操作代码将在UI线程上执行,这可能会导致一些滞后,因为它已经是一个相当重的控制。
任何其他建议或想法?我意识到这可能不是一个常见的问题。
谢谢,Tomas
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
I though it better to start a new thread, as I've accepted that I will have to do something about it myself.
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
这篇关于虚拟化非常大的Scrollviewer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!