Reader Level:
ARTICLE

Printing in WPF

Posted by Mahesh Chand Articles | WPF February 26, 2010
This article discusses the process of printing in WPF and how to print a FlowDocument, Control, and Window in WPF.
  • 0
  • 0
  • 77255

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 experienced with writing printing applications using GDI or GDI+, you will have to start thinking differently. 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 that 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 directly 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.

Further Readings

Here are some more WPF and Windows Forms Printing related articles.

Printing a Control in WPF using C# by Mahesh Chand on Jun 12, 2010
This code snippet explains how to print a control, user control, container, or a Window in WPF using C#.

How To Print Part of the page in C# by Harshit Vyas on Nov 11, 2010
In this article we will see how to print a portion of a page in C#.

Print a Text File in C# by Mahesh Chand on Jun 06, 2007
In this article, you will learn how to print a text file in C#. The attached project lets you browse and open a text file and print it to a printer.

Print API in Silverlight 4 by Diptimaya Patra on Jun 22, 2010
In this article we will see how the Print API can be used in Silverlight 4.

Printing in C# by Mike Gold on Jan 20, 2006
An application show you all Printing, Print Preview functionality using C#.

Prnting out your W2 Form using C# and .NET by Mike Gold on Jan 04, 2006
This article covers a fairly practical aspect of using a computer - dealing with forms.

Printing windows form in C#.net by Rajalakshmi on Jan 31, 2008
This article tells you how to print a windows form in c#.net at runtime.

erver'>
Article Extensions
Contents added by Mahesh Chand on Jun 12, 2010

Print a Control, User Control or a Window in WPF

In WPF, a Visual is an object that is parent class of all user interfaces including UIElement, Containers, Controls, UserControls, and even Viewport3DVisual. If you notice all control or user controls classes, they are inherited from a UIElement class.

The PrintVisual print a Visual object. That means, by using the PrintVisual method, we can print any control, container, Window or user control.

The following code snippet in creates a PrintDialog object and calls its PrintVisual method by passing a UserControl to print the UserControl. Using this method, we can print any controls in WPF including a Window, page, or a ListBox.   

PrintDialog printDlg = new PrintDialog();
UserControl1 uc = new UserControl1();
printDlg.PrintVisual(uc, "User Control Printing."); 

 

What if you want to print a Grid control or any other control?

As said above, printing any control in WPF is same process. Just pass the Grid or other control in the PrintVisual method of PrintDialog.

PrintDialog printDlg = new PrintDialog();

printDlg.PrintVisual(grid1, "Grid Printing.");

How about printing the entire Window?

For entire window, you can either pass the window object or this keyword. This time, you pass "this" that is the object of current Window where you are writing this code.

PrintDialog printDlg = new PrintDialog();

printDlg.PrintVisual(this, "Window Printing.");

 

COMMENT USING

Trending up