Printing FlowDocument in WPF
This article demonstrates how to create a FlowDocument dynamically and print it in WPF.
Introduction
Printing in WPF has changed drastically in WPF.
If are used to write printing applications using GDI or GDI+, you will
have to start thinking in a different way. Now, you have to think of a
FlowDocument. If you want to print in WPF, what you actually need to do
is, create a FlowDocument object, add your contents what you would like
to print to this FlowDocument and send this FlowDocument object to the
printer.
Before you write your printing code, you must make sure you import these two namespaces in your project.
using System.Printing;
using System.Windows.Documents;
The System.Windows.Documents namespace is
already added to your project when you create a new WPF project. The
System.Printing namespace is required for the printing functionality.
Printing Process
OK, here are the steps required to print a FlowDocument in WPF.
1. Create a PrintDialog
The following code creates a PrintDialog in WPF code.
// Create a PrintDialog
PrintDialog printDlg = new PrintDialog();
2. Create a FlowDocument
The
FlowDocument object is used to create a FlowDocument. It has items such
as a paragraph, run, line, image and so on. The following code snippet
creates a FlowDocument and adds a line of text to the document.
// Create a FlowDocument dynamically.
FlowDocument doc = new FlowDocument(new Paragraph(new Run("Some text goes here")));
doc.Name = "FlowDoc";
3. Create an IDocumentPaginatorSource
The third step is to create an
IDocumentPaginatorSource object from a FlowDocument that is pretty
simple as listed here. You direct convert a FlowDocument to an
IDocumentPaginatorSource.
// Create IDocumentPaginatorSource from FlowDocument
IDocumentPaginatorSource idpSource = doc;
4. Call PrintDialog.PrintDocument method
The last step is to call
PrintDialog.PrintDocument method to call the print dialog that will
allow you to select a printer and send document to the printer to print
it. The PrintDocument method of PrintDialog takes a DocumentPaginator
object that you can get from IDocumentPaginatorSource.DocumentPaginator
property as listed in the following code:
// Call PrintDocument method to send document to printer
printDlg.PrintDocument(idpSource.DocumentPaginator, "Hello WPF Printing.");
The Application
Ok now you know what is required to print
FlowDocuments in WPF, let's create a working application. Create a WPF
Application and add a Button control to the Window.
After that, change the Name attribute of the
button to PrintSimpleTextButton and double click on it to write a button
click event handler. My XAML code of MainWindow looks like Listing 1.
<Window x:Class="PrintingTextSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Print Simple Text" Height="37" HorizontalAlignment="Left" Margin="22,21,0,0"
Name="PrintSimpleTextButton" VerticalAlignment="Top" Width="134"
Click="PrintSimpleTextButton_Click" />
</Grid>
</Window>
Listing 1
Now I am going to create a FlowDocument in WPF.
The CreateFlowDocument method in Listing 2 creates and returns a
FlowDocument object. The Paragraph, Section, Underline objects represent
a paragraph, section, and underline of a document. You can add as many
contents to your FlowDocument here. I am writing a tutorial on working
with FlowDocuments in WPF. Stay tuned for it.
/// <summary>
/// This method creates a dynamic FlowDocument. You can add anything to this
/// FlowDocument that you would like to send to the printer
/// </summary>
/// <returns></returns>
private FlowDocument CreateFlowDocument()
{
// Create a FlowDocument
FlowDocument doc = new FlowDocument();
// Create a Section
Section sec = new Section();
// Create first Paragraph
Paragraph p1 = new Paragraph();
// Create and add a new Bold, Italic and Underline
Bold bld = new Bold();
bld.Inlines.Add(new Run("First Paragraph"));
Italic italicBld = new Italic();
italicBld.Inlines.Add(bld);
Underline underlineItalicBld = new Underline();
underlineItalicBld.Inlines.Add(italicBld);
// Add Bold, Italic, Underline to Paragraph
p1.Inlines.Add(underlineItalicBld);
// Add Paragraph to Section
sec.Blocks.Add(p1);
// Add Section to FlowDocument
doc.Blocks.Add(sec);
return doc;
}
Listing 2
Now, we are going to write code on the button click event handler that will create a FlowDocument and print it.
As
you can see from the code listed in Listing 3, we follow the steps
discussed in the previous section. I first create a PrintDialog, then
create a FlowDocument, convert it to an IDocumentPaginatorSource and in
the end, call PrintDialog.PrintDocument method.
private void PrintSimpleTextButton_Click(object sender, RoutedEventArgs e)
{
// Create a PrintDialog
PrintDialog printDlg = new PrintDialog();
// Create a FlowDocument dynamically.
FlowDocument doc = CreateFlowDocument();
doc.Name = "FlowDoc";
// Create IDocumentPaginatorSource from FlowDocument
IDocumentPaginatorSource idpSource = doc;
// Call PrintDocument method to send document to printer
printDlg.PrintDocument(idpSource.DocumentPaginator, "Hello WPF Printing.");
}
Listing 3
Summary
In this article, I demonstrated how to create a
FlowDocument object dynamically and send it to a printer to print it by
using a PrintDialog control available in WPF.