C# 如何在WPF中向FlowDocument添加页脚?
我的应用程序中有一个C# 如何在WPF中向FlowDocument添加页脚?,c#,wpf,flowdocument,C#,Wpf,Flowdocument,我的应用程序中有一个流程文档,如下所示: <FlowDocumentScrollViewer Grid.Row="1"> <FlowDocument> <Section> <Paragraph>Header</Paragraph> </Section> <Section
流程文档
,如下所示:
<FlowDocumentScrollViewer Grid.Row="1">
<FlowDocument>
<Section>
<Paragraph>Header</Paragraph>
</Section>
<Section>
<Paragraph >
Footer
</Paragraph>
</Section>
</FlowDocument>
</FlowDocumentScrollViewer>
标题
页脚
我想要的是将第一个
设置为保留在文档顶部作为页眉,将第二个设置为保留在文档底部作为页脚
谁能告诉我最好的方法吗?你可以试试这个。。希望这有帮助
<Section Name="MainBody" SectionExtensions.ResetPageNumbers="True">
<!-- Add the document title to the header -->
<SectionExtensions.HeaderTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0,0,0,1">
<TextBlock Text="Document title" FontSize="16" />
</Border>
</DataTemplate>
</SectionExtensions.HeaderTemplate>
<!-- Add the page count to the footer -->
<SectionExtensions.FooterTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0,1,0,0">
<TextBlock Text="{Binding}" FontSize="16" />
</Border>
</DataTemplate>
</SectionExtensions.FooterTemplate>
<Paragraph>
...
</Paragraph>
</Section>
...
起点是一篇博客文章,其中显示了。其局限性在于,它旨在直接与打印API一起使用。它不能直接用于查看器,因为查看器要求其文档为FlowDocument
,并且不可能在子类中重写DocumentPaginator
我为FlowDocumentPageViewer
找到的解决方案有几个部分。我还没有尝试将其改编为FlowDocumentScrollViewer
,但使用相同的原则可能是可行的
自定义XAML模板
我首先使用Blend提取FlowDocumentPageViewer
的默认XAML模板。实际上我还是想删除一些位,但是页眉/页脚的关键更改是(作为统一的差异)
-
+
您应该能够了解如何覆盖OnPrintCommand
以将CustomDocumentPaginator
发送到XpsDocumentWriter
而不是((IDocumentPaginatorSource)文档)。DocumentPaginator
包装文档分页器
我说的起点是一篇博客文章,它展示了如何包装DocumentPaginator
。有一些微妙之处它没有提到,可能是因为它打算打印一次文档,所以作者没有遇到它们
DocumentPage
是一次性的。当您从包装的分页器中获得一页时,您有责任处理它。如果您不这样做,您可能会发现,当您来回导航时,您会得到随机的参数异常:在将包装页的Visual
添加到ContainerVisual
时,指定的Visual已经是另一个Visual的子项或合成目标的根
另一种获取ArgumentException
的方法是,当您已经有一个页面的包装副本时,尝试包装页面。例如,如果您打印,可能会发生这种情况,因为XpsDocumentWriter
将请求当前呈现到屏幕上的页面的副本
因此,您需要仔细管理页面的生命周期。我的paginator包装的修改版本是
类DocumentPaginatorWrapper:DocumentPaginator
{
私有厚度(u边);;
私人文件发布者(Paginator);;
//需要避免打印时出现“ArgumentException:指定的Visual已是另一个Visual的子级或CompositionTarget的根”的情况
私有IDictionary_PageCache=新字典();
公共文档分页器包装(文档分页器分页器,厚度边距)
{
_保证金=保证金;
_Paginator=Paginator;
this.PageSize=paginator.PageSize;
//事件
paginator.ComputePageCountCompleted+=(s,ev)=>此.onComputerPageCountCompleted(ev);
paginator.GetPageCompleted+=(s,ev)=>this.OnGetPageCompleted(ev);
paginator.PagesChanged+=(s,ev)=>此.OnPagesChanged(ev);
}
公共覆盖文档页面GetPage(内部页码)
{
文档页面缓存页面;
if(_PageCache.TryGetValue(pageNumber,out cachedPage)&&cachedPage.Visual!=null)返回cachedPage;
DocumentPage page=_Paginator.GetPage(页码);
//为转换创建可视包装并添加额外内容
ContainerVisual newpage=新ContainerVisual();
//要转换包装的页面,请添加页眉和页脚。
//这是非常特殊的。
...
//注意:我们假设page.BleedBox的X=0,Y=0,Size=page.PageSize
cachedPage=newdocumentpagewrapper(page,newpage,PageSize,new Rect(PageSize),new Rect(page.ContentBox.X,page.ContentBox.Y,page.ContentBox.Width+_Margin.Left+_Margin.Right,page.ContentBox.Height+_Margin.Top+_Margin.Bottom));
_PageCache[pageNumber]=缓存页面;
返回缓存页;
}
public override bool IsPageCountValid{get{return}Paginator.IsPageCountValid;}
公共重写int PageCount{get{return}Paginator.PageCount;}
公共覆盖大小PageSize
{
获取{var value=_Paginator.PageSize;返回新大小(value.Width+_Margin.Left+_Margin.Right,value.Height+_Margin.Top+_Margin.Bottom);}
设置{u Paginator.PageSize=新大小(value.Width-_Margin.Left-_Margin.Right,value.Height-_Margin.Top-_Margin.Bottom);}
}
公共重写IDocumentPaginatorSource{get{return}
}
///
///在处理我们返回的页面时,有必要处理包装好的DocumentPaginator返回的页面,
///因为否则,我们会因页面.Visual仍在使用而不一致地获得ArgumentException。
///
类DocumentPageWrapper:DocumentPage
{
内部DocumentPageWrapper(DocumentPageOriginalPage、可视、大小pageSize、Rect bleedBox、Rect contentBox)
:base(可视、页面大小、bleedBox、contentBox)
{