WPF DocumentViewer:使用内部 link 导航在第一次点击时不准确
WPF DocumentViewer : Navigate using internal link not accurate on first click
在 WPF 中,我在 Frame 控件中有一个 DocumentViewer。 DocumentViewer 显示一个用 MS Word 生成的 XPS 文档。该文档包含 Table 的内容以帮助浏览文档。
DocumentViewer 允许用户单击这些 link 并导航到相应的页面,只要将 DocumentViewer 放置在允许导航的控件(例如框架)中即可。
当用户第一次导航时,DocumentViewer 不会准确跳转到 linked 位置。文档中越远,跳转位置与实际位置之间的 space 就越大。看起来每页都有一定数量的偏差。在第一次 link 单击后,导航工作正常。
使用框架上的导航按钮向后导航时,link 准确度在加载第一个视图后立即再次下降。
根据 this post,第一次单击 link 后会创建一个新的 DocumentViewer。这似乎创建了一个按预期工作的实例。
为什么初始实例导航不准确,如何解决?
下面截取的代码可用于重现该问题。
XAML 里面 Window:
<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 文档包含一个 TOC 和两章,它们之间有大约 40 页。导航到第二章时问题变得很清楚(关闭了 3 页)。
将近两年后,我重新审视了这个问题并找到了解决方案。
正如我原来的 post 中所见,我使用了一个 Frame
,其内容设置为 DocumentViewer
。 Frame
用于在 XPS 文档中启用导航。
一些细节:
第一次加载文档时,Frame
的实际 Content
设置为 DocumentViewer
。 Frame
的 Source
是 null
。单击文档中的 link 时,Frame
会导航到该位置,但准确性很差,如我上面的问题所述。在幕后,Frame
已将其 Content
更改为 FixedDocumentSequence
的实例,并将其 Source
设置为单击的 Uri
。从现在开始,导航工作非常准确。
解决方法:
解决方法其实很简单。而不是将 DocumentViewer
放入 Frame
并将 DocumentViewer.Document
属性 设置为实际的 FixedDocumentSequence
,Frame.Source
属性 应该设置为 FixedDocumentSequence
的 Uri
。
FixedDocumentSequence
实现了可用于检索 Uri
.
的显式接口 属性 IUriContext.BaseUri
在我的代码中,我使用绑定来设置源:
<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>
在后面的代码中,您可以通过这样做来完成同样的事情:
XpsDocument xpsDoc = new XpsDocument(Path, FileAccess.Read);
FixedDocumentSequence document = xpsDoc.GetFixedDocumentSequence();
frame.Source = ((System.Windows.Markup.IUriContext)document).BaseUri;
在 WPF 中,我在 Frame 控件中有一个 DocumentViewer。 DocumentViewer 显示一个用 MS Word 生成的 XPS 文档。该文档包含 Table 的内容以帮助浏览文档。
DocumentViewer 允许用户单击这些 link 并导航到相应的页面,只要将 DocumentViewer 放置在允许导航的控件(例如框架)中即可。
当用户第一次导航时,DocumentViewer 不会准确跳转到 linked 位置。文档中越远,跳转位置与实际位置之间的 space 就越大。看起来每页都有一定数量的偏差。在第一次 link 单击后,导航工作正常。
使用框架上的导航按钮向后导航时,link 准确度在加载第一个视图后立即再次下降。
根据 this post,第一次单击 link 后会创建一个新的 DocumentViewer。这似乎创建了一个按预期工作的实例。
为什么初始实例导航不准确,如何解决?
下面截取的代码可用于重现该问题。
XAML 里面 Window:
<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 文档包含一个 TOC 和两章,它们之间有大约 40 页。导航到第二章时问题变得很清楚(关闭了 3 页)。
将近两年后,我重新审视了这个问题并找到了解决方案。
正如我原来的 post 中所见,我使用了一个 Frame
,其内容设置为 DocumentViewer
。 Frame
用于在 XPS 文档中启用导航。
一些细节:
第一次加载文档时,Frame
的实际 Content
设置为 DocumentViewer
。 Frame
的 Source
是 null
。单击文档中的 link 时,Frame
会导航到该位置,但准确性很差,如我上面的问题所述。在幕后,Frame
已将其 Content
更改为 FixedDocumentSequence
的实例,并将其 Source
设置为单击的 Uri
。从现在开始,导航工作非常准确。
解决方法:
解决方法其实很简单。而不是将 DocumentViewer
放入 Frame
并将 DocumentViewer.Document
属性 设置为实际的 FixedDocumentSequence
,Frame.Source
属性 应该设置为 FixedDocumentSequence
的 Uri
。
FixedDocumentSequence
实现了可用于检索 Uri
.
IUriContext.BaseUri
在我的代码中,我使用绑定来设置源:
<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>
在后面的代码中,您可以通过这样做来完成同样的事情:
XpsDocument xpsDoc = new XpsDocument(Path, FileAccess.Read);
FixedDocumentSequence document = xpsDoc.GetFixedDocumentSequence();
frame.Source = ((System.Windows.Markup.IUriContext)document).BaseUri;