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