C# Print PDF documents from a WPF application

Printing
3/21/2014

This code sample shows how to print PDF documents from a WPF application using C#.

First create a window with a print button in XAML:

1 <Window x:Class="WpfApplication1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" 5 Height="156" 6 Width="250"> 7 <Grid> 8 <Button Name="buttonPrint" Content="Print a PDF" 9 Height="26" Width="100" Margin="50,50,0,0" 10 HorizontalAlignment="Left" VerticalAlignment="Top" 11 Click="ButtonPrintPressed" /> 12 </Grid> 13 </Window>

The windows looks like this:
WpfWindow.PNG
Add the following handler for the button pressed event:

1 private void ButtonPrintPressed(object sender, RoutedEventArgs e) 2 { 3 var openFileDialog = new Microsoft.Win32.OpenFileDialog 4 { 5 DefaultExt = ".pdf", 6 Filter = "PDF files (*.pdf)|*.pdf|All files (*.*)|*.*" 7 }; 8 var fileOpenResult = openFileDialog.ShowDialog(); 9 if (fileOpenResult != true) 10 { 11 return; 12 } 13 ...

Pressing the "print" button now shows the familiar file open dialog:

WpfPrintFile.PNG

After the user selects the PDF file, we open a print dialog:

1 ... 2 PrintDialog printDialog = new PrintDialog(); 3 printDialog.PageRangeSelection = PageRangeSelection.AllPages; 4 printDialog.UserPageRangeEnabled = true; 5 bool? doPrint = printDialog.ShowDialog(); 6 if (doPrint != true) 7 { 8 return; 9 } 10 ...

Note the 'PageRangeSelection = true' as it is disabled by default. After selecting a PDF, this print dialog appears:

WpfPrintDialog.PNG

After the "print" button is pressed it is time to render the PDF document to WPF (using PDFRasterizer.NET) and to actually print it:

1 //open the pdf file 2 FixedDocument fixedDocument; 3 using (FileStream pdfFile = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read)) 4 { 5 Document document = new Document(pdfFile); 6 RenderSettings renderSettings = new RenderSettings(); 7 ConvertToWpfOptions renderOptions = new ConvertToWpfOptions { ConvertToImages = false }; 8 renderSettings.RenderPurpose = RenderPurpose.Print; 9 renderSettings.ColorSettings.TransformationMode = ColorTransformationMode.HighQuality; 10 //convert the pdf with the rendersettings and options to a fixed-size document which can be printed 11 fixedDocument = document.ConvertToWpf(renderSettings, renderOptions); 12 } 13 printDialog.PrintDocument(fixedDocument.DocumentPaginator, "Print");

The full code sample

Here are the above snippets stitched together:

1 using Microsoft.Win32; 2 using System.IO; 3 using System.Windows; 4 using System.Windows.Controls; 5 using System.Windows.Documents; 6 using TallComponents.PDF.Rasterizer; 7 using TallComponents.PDF.Rasterizer.Configuration; 8 9 namespace PrintPDFSimple 10 { 11 public partial class MainWindow : Window 12 { 13 public MainWindow() 14 { 15 InitializeComponent(); 16 } 17 18 private void ButtonPrintPressed(object sender, RoutedEventArgs e) 19 { 20 //get the pdf file the user selected 21 OpenFileDialog openFileDialog = new OpenFileDialog 22 { 23 DefaultExt = ".pdf", 24 Filter = "PDF files (*.pdf)|*.pdf|All files (*.*)|*.*" 25 }; 26 bool? fileOpenResult = openFileDialog.ShowDialog(); 27 if (fileOpenResult != true) 28 { 29 return; 30 } 31 32 //show a printdialog to user where attributes can be changed 33 PrintDialog printDialog = new PrintDialog(); 34 printDialog.PageRangeSelection = PageRangeSelection.AllPages; 35 printDialog.UserPageRangeEnabled = true; 36 bool? doPrint = printDialog.ShowDialog(); 37 if (doPrint != true) 38 { 39 return; 40 } 41 42 //open the pdf file 43 FixedDocument fixedDocument; 44 using (FileStream pdfFile = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read)) 45 { 46 Document document = new Document(pdfFile); 47 RenderSettings renderSettings = new RenderSettings(); 48 ConvertToWpfOptions renderOptions = new ConvertToWpfOptions { ConvertToImages = false }; 49 renderSettings.RenderPurpose = RenderPurpose.Print; 50 renderSettings.ColorSettings.TransformationMode = ColorTransformationMode.HighQuality; 51 //convert the pdf with the rendersettings and options to a fixed-size document which can be printed 52 fixedDocument = document.ConvertToWpf(renderSettings, renderOptions); 53 } 54 printDialog.PrintDocument(fixedDocument.DocumentPaginator, "Print"); 55 } 56 } 57 }

Print dialog limitations

The print dialog has the following limitiations:

  • No preview
  • No scale to fit the printable area.
  • No progress indicator
  • No 2-up printing

It appears that it is designed for selecting a printer and using its capabilities, but not so much for the document which is being printed.