打印 WPF FlowDocument

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/345009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:51:00  来源:igfitidea点击:

Printing a WPF FlowDocument

wpfprinting

提问by Jason

I'm building a demo app in WPF, which is new to me. I'm currently displaying text in a FlowDocument, and need to print it.

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

The code I'm using looks like this:

我正在使用的代码如下所示:

        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 is my FlowDocument, and for now I'm using the default printer instead of allowing the user to specify print options. It works OK, except that after the document prints, the FlowDocument displayed on screen has changed to to use the settings I specified for printing.

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

I can fix this by manually resetting everything after I print, but is this the best way? Should I make a copy of the FlowDocument before I print it? Or is there another approach I should consider?

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

回答by Cheeso

yes, make a copy of the FlowDocument before printing it. This is because the pagination and margins will be different. This works for me.

是的,在打印之前制作 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);
        }

    }

回答by Nir

You can use the code from the URL below, it wraps the flow document in a fixed document and prints that, the big advantage is that you can use it to add margin, headers and footers.

您可以使用以下 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

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

回答by dotNET

The following works with both text and non-text visuals:

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

//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");
}

回答by Allan

I am also generating a WPF report off a Flow document, but I am purposely using the flow document as a print preview screen. I there for want the margins to be the same. You can read about how I did this here.

我还根据 Flow 文档生成 WPF 报告,但我特意将 Flow 文档用作打印预览屏幕。我在那里希望边距相同。你可以在这里阅读我是如何做到的

In your scenario I'm thinking why not just make a copy of your settings, instead of the entire flow document. You can then re-apply the settings if you wish to return the document back to it's original state.

在你的场景中,我在想为什么不复制你的设置,而不是整个流程文档。如果您希望将文档恢复到原始状态,您可以重新应用这些设置。