How to Print Preview when using a DocumentPaginator to print? How to Print Preview when using a DocumentPaginator to print? wpf wpf

How to Print Preview when using a DocumentPaginator to print?


So I got it working after reading Pro WPF in C# 2008 (Page 726).

Basically the DocumentViewer class needs an XPS file to present a print preview of it. So I do the following:

PrintDialog dialog = new PrintDialog();var paginator = new RowPaginator(rowsToPrint) { PageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight) };string tempFileName = System.IO.Path.GetTempFileName();//GetTempFileName creates a file, the XpsDocument throws an exception if the file already//exists, so delete it. Possible race condition if someone else calls GetTempFileNameFile.Delete(tempFileName); using (XpsDocument xpsDocument = new XpsDocument(tempFileName, FileAccess.ReadWrite)){    XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);    writer.Write(paginator);    PrintPreview previewWindow = new PrintPreview                                     {                                         Owner = this,                                         Document = xpsDocument.GetFixedDocumentSequence()                                     };    previewWindow.ShowDialog();}

I'm creating the print dialog to get the default page size. There's probably a better way to do this.XpsDocument is in ReachFramework.dll (Namespace System.Windows.Xps.Packaging);

Here's the PrintPreview Window.

<Window x:Class="WPFPrintTest.PrintPreview"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    x:Name="previewWindow"    Title="PrintPreview" Height="800" Width="800">    <Grid>        <DocumentViewer Name="viewer"                         Document="{Binding ElementName=previewWindow, Path=Document}" />    </Grid></Window>

The code behind just has a Document property like so:

public IDocumentPaginatorSource Document{    get { return viewer.Document; }    set { viewer.Document = value; }}


The following code uses a MemoryStream to do a print preview.

MemoryStream stream = new MemoryStream();Package package = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite);var uri = new Uri(@"memorystream://myXps.xps");PackageStore.AddPackage(uri, package);var xpsDoc = new XpsDocument(package);xpsDoc.Uri = uri;XpsDocument.CreateXpsDocumentWriter(xpsDoc).Write(paginator);documentViewer.Document = xpsDoc.GetFixedDocumentSequence();

Remember to use close() and remove package from PackageStore when the print preview is closed.


WPF doesn't come with any built-in Print Preview functionality, if you want to do a print preview, you're going to have to construct it yourself. Fortunately, it's shouldn't be that difficult.

You've already got the pagination code, which creates your DocumentPage objects. These objects contain a Visual, which you can go ahead and display in your UI.

What you'll end up doing, is paginating your entire document, collecting all the DocumentPage objects, then displaying their visuals inside of a scrolling StackPanel or something similar. These are the same DocumentPage objects that you can then send to the printer.