问题描述
在WPF中,我在Frame控件中有一个DocumentViewer. DocumentViewer显示了使用MS Word生成的XPS文档.该文档包含一个目录,可帮助您浏览文档.
In WPF I have a DocumentViewer inside a Frame control. The DocumentViewer shows an XPS document generated with MS Word. The document contains a Table of Content to help navigate through the document.
只要将DocumentViewer放在允许导航的控件(例如框架)中,DocumentViewer允许用户单击这些链接并导航到相应的页面.
The DocumentViewer allows the user to click these links and navigate to the corresponding pages, as long as the DocumentViewer is placed in a control that allows for navigation (e.g. a Frame).
当用户第一次导航时,DocumentViewer不能准确跳转到链接位置.文档越远,跳转的位置和实际位置之间的空间就越大.看起来每页有一定数量的减少.第一次单击链接后,导航正常运行.
When the user navigates for the first time, the DocumentViewer does not jump accurately to the linked location. The further away in the document, the larger the space between the jumped location and the actual location becomes. It looks like it is off by a certain amount per page. After this first link click, the navigation works perfectly fine.
使用框架上的导航按钮向后导航时,链接精度会在加载第一个视图后立即再次表现出孔隙.
When navigating back using the navigation buttons on the frame, the link accuracy behaves pore again as soon as the very first view is loaded.
根据此帖子,首次单击链接后,将创建一个新的DocumentViewer.似乎创建了一个可以正常工作的实例.
According to this post, a new DocumentViewer is being created after clicking on the link for the first time. It seems that that creates an instance that works as expected.
为什么初始实例无法正确导航,以及如何解决此问题?
Why is the initial instance not navigating accurately and how to solve this?
下面插入的代码可用于重现此问题.
The code snipped below can be used to reproduce the issue.
窗口内的XAML:
<Frame>
<Frame.Content>
<DocumentViewer Name="docViewer" />
</Frame.Content>
</Frame>
后面的代码:
public MainWindow()
{
InitializeComponent();
LoadDoc();
}
private void LoadDoc()
{
XpsDocument xpsDoc = new XpsDocument("test.xps", FileAccess.Read);
docViewer.Document = xpsDoc.GetFixedDocumentSequence();
}
test.xps文档包含一个目录和两个章节,中间共有40页.导航到第二章时,问题变得很清楚(每页3页).
The test.xps document contains a TOC and two chapters with around 40 pages in between them. The issue becomes clear when navigating to the second chapter (it is off by 3 pages).
推荐答案
将近两年后,我重新审视了此问题并找到了解决方案.
After almost two years I've revisited this issue and found the solution.
从我的原始帖子中可以看出,我使用了Frame
,其内容设置为DocumentViewer
. Frame
用于启用XPS文档中的导航.
As can be seen in my original post, I used a Frame
with its content set to a DocumentViewer
. The Frame
is used to enable navigation within the XPS document.
一些详细信息:
首次加载文档时,Frame
的实际Content
设置为DocumentViewer
. Frame
的Source
是null
.单击文档中的链接时,Frame
会导航到该位置,但是准确性较差,如上面我的问题中所述.在后台,Frame
将其Content
更改为FixedDocumentSequence
的实例,并将其Source
设置为单击的Uri
.从现在开始,导航功能将非常准确.
When the document loads for the first time, the actual Content
of the Frame
is set to the DocumentViewer
. The Source
of the Frame
is null
. When clicking a link in the document, the Frame
navigates to the location, but has poor accuracy, as described in my question above. Behind the scenes, the Frame
has changed its Content
to an instance of FixedDocumentSequence
and its Source
is set to the clicked Uri
. From now on, the navigation works perfectly accurate.
解决方案:
解决方案实际上非常简单.代替将DocumentViewer
放在Frame
内并将DocumentViewer.Document
属性设置为实际的FixedDocumentSequence
,应将Frame.Source
属性设置为FixedDocumentSequence
的Uri
.
The solution is actually very simple. Instead of putting a DocumentViewer
inside the Frame
and setting the DocumentViewer.Document
property to the actual FixedDocumentSequence
, the Frame.Source
property should be set to the Uri
of the FixedDocumentSequence
.
FixedDocumentSequence
实现显式接口属性IUriContext.BaseUri
,可用于检索Uri
.
FixedDocumentSequence
implements the explicit interface property IUriContext.BaseUri
that can be used to retrieve the Uri
.
在我的代码中,我使用绑定来设置源:
In my code, I use a binding to set the source:
<UserControl x:Class="XPSDocumentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:System.Windows.Markup;assembly=System.Xaml" >
<Grid>
<Frame Margin="5" NavigationUIVisibility="Hidden"
Source="{Binding Path=Document.(base:IUriContext.BaseUri)}" />
</Grid>
</UserControl>
在后面的代码中,您可以这样做:
In code behind you could accomplish the same by doing this:
XpsDocument xpsDoc = new XpsDocument(Path, FileAccess.Read);
FixedDocumentSequence document = xpsDoc.GetFixedDocumentSequence();
frame.Source = ((System.Windows.Markup.IUriContext)document).BaseUri;
这篇关于WPF DocumentViewer:第一次单击时使用内部链接导航不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!