打印WPF FlowDocument

39

我正在使用 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吗?还是应该考虑其他方法?


11
你的问题就是我的答案。谢谢! - BrokeMyLegBiking
4个回答

41

在打印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);
        }

    }

6
这似乎只能打印文本,如何打印BlockUIContainer? - Beaker
@Beaker 请查看这个解决方案,它允许您打印图像和其他BlockUI容器:https://dev59.com/gmDVa4cB1Zd3GeqPhd1Q#18088609 - Marwan مروان

8

2
以下内容适用于文本和非文本视觉元素:
//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");
}

0

我也正在使用Flow文档生成WPF报告,但我有意将Flow文档用作打印预览屏幕。因此,我希望边距保持相同。您可以在这里阅读有关如何实现的内容。

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


我使用WayBackMachine修复了这个答案中的链接。http://www.archive.org/index.php - Dennis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接