【问题标题】:Printing a WPF FlowDocument打印 WPF FlowDocument
【发布时间】:2010-09-25 14:12:34
【问题描述】:

我正在 WPF 中构建一个演示应用程序,这对我来说是新的。我目前正在 FlowDocument 中显示文本,需要打印它。

我使用的代码如下所示:

        PrintDialog pd = new PrintDialog();
        fd.PageHeight = pd.PrintableAreaHeight;
        fd.PageWidth = pd.PrintableAreaWidth;
        fd.PagePadding = new Thickness(50);
        fd.ColumnGap = 0;
        fd.ColumnWidth = pd.PrintableAreaWidth;

        IDocumentPaginatorSource dps = fd;
        pd.PrintDocument(dps.DocumentPaginator, "flow doc");

fd 是我的 FlowDocument,现在我使用默认打印机而不是允许用户指定打印选项。它工作正常,除了文档打印后,屏幕上显示的 FlowDocument 已更改为使用我指定的打印设置。

我可以通过在打印后手动重置所有内容来解决此问题,但这是最好的方法吗?我应该在打印之前复制 FlowDocument 吗?还是我应该考虑另一种方法?

【问题讨论】:

  • 你的问题就是我的答案。谢谢!

标签: wpf printing


【解决方案1】:

您可以使用下面 URL 中的代码,它将流文档包装在一个固定文档中并打印出来,最大的优点是您可以使用它来添加边距、页眉和页脚。

https://web.archive.org/web/20150502085246/http://blogs.msdn.com:80/b/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header-margin.aspx

【讨论】:

    【解决方案2】:

    是的,在打印之前复制 FlowDocument。这是因为分页和边距会有所不同。这对我有用。

        private void DoThePrint(System.Windows.Documents.FlowDocument document)
        {
            // Clone the source document's content into a new FlowDocument.
            // This is because the pagination for the printer needs to be
            // done differently than the pagination for the displayed page.
            // We print the copy, rather that the original FlowDocument.
            System.IO.MemoryStream s = new System.IO.MemoryStream();
            TextRange source = new TextRange(document.ContentStart, document.ContentEnd);
            source.Save(s, DataFormats.Xaml);
            FlowDocument copy = new FlowDocument();
            TextRange dest = new TextRange(copy.ContentStart, copy.ContentEnd);
            dest.Load(s, DataFormats.Xaml);
    
            // Create a XpsDocumentWriter object, implicitly opening a Windows common print dialog,
            // and allowing the user to select a printer.
    
            // get information about the dimensions of the seleted printer+media.
            System.Printing.PrintDocumentImageableArea ia = null;
            System.Windows.Xps.XpsDocumentWriter docWriter = System.Printing.PrintQueue.CreateXpsDocumentWriter(ref ia);
    
            if (docWriter != null && ia != null)
            {
                DocumentPaginator paginator = ((IDocumentPaginatorSource)copy).DocumentPaginator;
    
                // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
                paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight);
                Thickness t = new Thickness(72);  // copy.PagePadding;
                copy.PagePadding = new Thickness(
                                 Math.Max(ia.OriginWidth, t.Left),
                                   Math.Max(ia.OriginHeight, t.Top),
                                   Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), t.Right),
                                   Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), t.Bottom));
    
                copy.ColumnWidth = double.PositiveInfinity;
                //copy.PageWidth = 528; // allow the page to be the natural with of the output device
    
                // Send content to the printer.
                docWriter.Write(paginator);
            }
    
        }
    

    【讨论】:

    • 这好像只打印文本,请问如何打印BlockUIContainer?
    • @Beaker 查看这个允许您打印图像和其他 BlockUIcontainer 的解决方案:stackoverflow.com/a/18088609/1243372
    【解决方案3】:

    我还从 Flow 文档中生成 WPF 报告,但我特意将 Flow 文档用作打印预览屏幕。我在那里希望边距相同。你可以阅读how I did this here

    在您的情况下,我在想为什么不只是复制您的设置,而不是整个流程文档。如果您希望将文档恢复到原始状态,则可以重新应用设置。

    【讨论】:

    【解决方案4】:

    以下内容适用于文本和非文本视觉效果:

    //Clone the source document
    var str = XamlWriter.Save(FlowDoc);
    var stringReader = new System.IO.StringReader(str);
    var xmlReader = XmlReader.Create(stringReader);
    var CloneDoc = XamlReader.Load(xmlReader) as FlowDocument;
    
    //Now print using PrintDialog
    var pd = new PrintDialog();
    
    if (pd.ShowDialog().Value)
    {
      CloneDoc.PageHeight = pd.PrintableAreaHeight;
      CloneDoc.PageWidth = pd.PrintableAreaWidth;
      IDocumentPaginatorSource idocument = CloneDoc as IDocumentPaginatorSource;
    
      pd.PrintDocument(idocument.DocumentPaginator, "Printing FlowDocument");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 2011-11-27
      相关资源
      最近更新 更多