将流文档放入分页时保持绑定

时间:2013-02-15 21:09:44

标签: .net wpf .net-4.0 reporting

我一直在尝试在.NET 4中使用WPF构建一个简单的报表和打印系统,经过无数个小时的拖网搜索和各种在线教程后,我有以下(简化)设置,该设置应该包含一个包含该文件的流文档报告模板,将数据源添加为datacontext,通过分页进行处理,最后得到可以显示/打印的内容。

报告在一个单独的内容文件(DefaultReport.xaml)的流文档中列出:

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Paragraph FontFamily="Arial">
        <Run Text="1"/>        
        <Run Text="{Binding Path=MyText}"/>
        <Run Text="3"/>        
    </Paragraph>
</FlowDocument>

datacontext是一个简单的对象:

private class MyDataContext {
    public string MyText { get; set; }
}

这样加载并组合在一起:

using (var stream = File.OpenRead("DefaultReport.xaml")) {
    FlowDocument document = (FlowDocument)XamlReader.Load(stream);                
    document.DataContext = new MyDataContext { MyText = "2" };

    flowReader.Document = document;           

    XpsDocument xpsDoc = LoadAsXPS(((IDocumentPaginatorSource)document).DocumentPaginator);
    fixedReader.Document = xpsDoc.GetFixedDocumentSequence();
    xpsDoc.Close();
}

LoadAsXPS将flowdocument转换为XpsDocument,如下所示:

public XpsDocument LoadAsXPS(DocumentPaginator paginator) {
     MemoryStream stream = new MemoryStream();
     Package docPackage = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite);

     Uri uri = new Uri(@"memorystream://myXps.xps");
     PackageStore.AddPackage(uri, docPackage);
     XpsDocument xpsDoc = new XpsDocument(docPackage);

     xpsDoc.Uri = uri;
     XpsDocument.CreateXpsDocumentWriter(xpsDoc).Write(paginator);

     return xpsDoc;
 }

flowReader和fixedReader输出整个操作的结果,并在xaml中定义为

 <FlowDocumentReader Name="flowReader" />
 <DocumentViewer Margin="0,10,0,0" Name="fixedReader" /> 

最终结果如下:

enter image description here

上半部分是我用于调试的FlowDocumentReader。这里一切都很好。 下半部分是包含我的分页文档的DocumentViewer,是我需要正常工作的。

如何完全可以通过分页过程保存绑定数据吗?

1 个答案:

答案 0 :(得分:4)

我在设定赏金后10分钟就知道了。图。

显然,在分配flowdocument datacontext之后,调度程序需要一点推动才能完成工作:

this.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() => { }));