WPF Printing in VB.NET

Printing has changed in WPF if you compare with GDI and GDI+. This article discusses the process of printing in WPF and how to create a FlowDocument dynamically and print it in WPF using a PrintDialog control.
  • 6330

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.

Categories

More Articles

© 2020 DotNetHeaven. All rights reserved.