Printing a WPF FlowDocument Printing a WPF FlowDocument wpf wpf

Printing a WPF FlowDocument


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

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


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.

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


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

//Clone the source documentvar 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 PrintDialogvar 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");}