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.
Imports
System.Printing
Imports
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
Dim printDlg As
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.
Dim doc
As 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
Dim idpSource As
IDocumentPaginatorSource = 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
Function CreateFlowDocument() As
FlowDocument
' Create a FlowDocument
Dim doc
As New
FlowDocument()
' Create a Section
Dim sec
As New
Section()
' Create first Paragraph
Dim p1
As New
Paragraph()
' Create and add a new Bold, Italic and
Underline
Dim bld
As New
Bold()
bld.Inlines.Add(New Run("First
Paragraph"))
Dim italicBld
As New
Italic()
italicBld.Inlines.Add(bld)
Dim underlineItalicBld
As 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
End Function
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 Sub
PrintSimpleTextButton_Click(ByVal sender
As Object,
ByVal e As
RoutedEventArgs)
' Create a PrintDialog
Dim printDlg
As New
PrintDialog()
' Create a FlowDocument dynamically.
Dim doc
As FlowDocument = CreateFlowDocument()
doc.Name = "FlowDoc"
' Create IDocumentPaginatorSource
from FlowDocument
Dim idpSource As
IDocumentPaginatorSource = doc
' Call PrintDocument method to send document
to printer
printDlg.PrintDocument(idpSource.DocumentPaginator,
"Hello WPF Printing.")
End Sub
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.