Introduction


The techniques covered here are all available in a downloadable project over at MSDN Samples:

This sample shows five aspects of printing, in relation to WPF.
With WPF, it has never been so easy to print your entire application, or build and format pages for printing.
 
 

1. Using DrawingContext



The DrawingContext (of a DrawingVisual) allows you to build up the print page, like a canvas.

This method allows you to build up the page in code with many methods, like adding shapes, images and text.

In the accompanying MSDN sample, we test the following:

Below is a snippet from the project:
 
DrawingVisual dv = new DrawingVisual();
 
var dc = dv.RenderOpen();
 
var rect = new Rect(new System.Windows.Point(20, 20), new System.Windows.Size(350, 240));
dc.DrawRoundedRectangle(System.Windows.Media.Brushes.Yellow, new Pen(Brushes.Purple, 2), rect, 20, 20);
 

2. Printing WPF Controls



WPF is specially good at printing, because you can print the rendered WPF controls, exactly as they are.

You can also save to file or apply the image to another surface (technique sometimes used in reflections)

In the example (shown above) there is a rotating Viewport3D, an Image and a TextBox for you to play with. Whatever state the controls are in, they will be printed.

This method uses PrintVisual, which takes any Visual as it's parameter

 

3. Printing Flow Documents



Flow documents are a great way to display formatted content, and they are easy to print.

The FlowDocumentReader is a rich user control, and printing pages can be controlled with the DocumentPaginator.

In this example, you can resize the window or change the layout style. If there is more than one page whenyou print, they will print on separate pages.

PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
    printDialog.PrintDocument(((IDocumentPaginatorSource)flowDocument).DocumentPaginator, "This is a Flow Document");

 

4. Making and Printing XPS Documents



XPS documents are a popular printing file format, and they are easy to make out of WPF controls.

Here we have an InkCanvas which you can draw on, enlarge the window, draw more and print.

This example shows how to use the XpsDocumentWriter to build the file.

The XPS file is then sent to the printer jobs queue.

FixedDocument doc = new FixedDocument();
 
PageContent pageContent = new PageContent();
((System.Windows.Markup.IAddChild)pageContent).AddChild(page);
doc.Pages.Add(pageContent); 
 
XpsDocument xpsd = new XpsDocument(filename, FileAccess.Write);
XpsDocument.CreateXpsDocumentWriter(xpsd).Write(doc);            
xpsd.Close();
 
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
    printDialog.PrintQueue.AddJob("MyInkCanvas print job", filename, true);

 

5. Capturing and Saving Video Stills



This example shows how you can "scrub" through a video and pull out frames to file and printer.

A slider bar is joined to the MediaElement to allow scene selection.

When you click print, the selected video frame is converted into a Jpeg, saved and printed.

byte[] screenshot = GetScreenShot(player, 1, 90);
FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite);
BinaryWriter binaryWriter = new BinaryWriter(fileStream);
binaryWriter.Write(screenshot);
binaryWriter.Close();
 
PrintDocument pd = new PrintDocument();
pd.PrintPage += (object printSender, PrintPageEventArgs printE) =>
{
    var img = System.Drawing.Image.FromFile(filename);
    printE.Graphics.DrawImageUnscaled(img, new System.Drawing.Point(0, 0));
};
 
PrintDialog dialog = new PrintDialog();
dialog.ShowDialog();
pd.Print(); 
 

6. Landscape Printing


In this example, there are two printing buttons. the first prints the parent grid, which prints the buttons, scrollviewer and it's contents. This shows as a cut off print.
The second example prints the TextBlock itself, which is inside a ScrollViewer, so is not actually constrained at all. This version prints perfectly stretched, showing all of the text.

private void Button_Click2(object sender, RoutedEventArgs e)
{
    PrintDialog printDialog = new PrintDialog();
    printDialog.PrintTicket.PageOrientation = PageOrientation.Landscape;
    printDialog.PrintVisual(printBlock, "Landscape working TextBox print");
}





Note: XPS and JPG files generated from the project are saved in ".../MyDocuments/PrintingTest"

Don't forget to download this project from MSDN Samples:
http://code.msdn.microsoft.com/WPF-Printing-Overview-f28c541a

(...and please rate it if you like it ;)