Table of Contents
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.
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
PrintDialog dialog =
new
PrintDialog();
if
(dialog.ShowDialog() !=
true
)
return
;
printGrid.Measure(
new
Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight));
printGrid.Arrange(
new
Rect(
new
Point(50, 50), printGrid.DesiredSize));
dialog.PrintVisual(printGrid,
"A WPF printing"
);
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 ;)
(...and please rate it if you like it ;)