Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing a WPF FlowDocument

Tags:

printing

wpf

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.

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.

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?

like image 567
Jason Avatar asked Dec 05 '08 20:12

Jason


People also ask

What is FlowDocument in WPF?

Flow documents are designed to optimize viewing and readability. Rather than being set to one predefined layout, flow documents dynamically adjust and reflow their content based on run-time variables such as window size, device resolution, and optional user preferences.

Is WPF a printer language?

WPF has a printing API that supports both basic and advanced printing features.


1 Answers

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);         }      } 
like image 58
Cheeso Avatar answered Sep 22 '22 00:09

Cheeso