You are on page 1of 4

PrintDocument Class

Defines a reusable object that sends output to a printer, when printing from a Windows Forms
application.Typically, you create an instance of the PrintDocument class, set the properties that describe
how to print, and call the Print method to start the printing process. Handle the PrintPage event where
you specify the output to print, by using the Graphics included in the PrintPageEventArgs. If you wish to
print from a Windows Presentation Foundation application, see the System.Printing namespace.

To specify the output to print, use the Graphics included in the PrintPageEventArgs. For example, to
specify a line of text that should be printed, draw the text using the Graphics.DrawString method.In
addition to specifying the output, you can indicate if there are additional pages to print by setting the
PrintPageEventArgs.HasMorePages property to true. The default is false, which indicates that there are no
more pages to print. Individual page settings can also be modified through the PageSettings and the print
job can be canceled by setting the PrintPageEventArgs.Cancel property to true. To print each page of a
document using different page settings, handle the QueryPageSettings event.

To associate the event with your event handler, add an instance of the PrintPageEventHandler delegate to
the event. The event handler is called whenever the event occurs

You can specify several default page settings through the DefaultPageSettings property. For example, the
PageSettings.Color property specifies whether the page prints in color, the PageSettings.Landscape
property specifies landscape or portrait orientation, and the PageSettings.Margins property specifies the
margins of the page.

Note
After printing has started, changes to page settings through the DefaultPageSettings property will not
affect pages being printed.

To specify settings on a page-by-page basis, handle the PrintPage or QueryPageSettings event and modify
the PageSettings argument included in the PrintPageEventArgs or QueryPageSettingsEventArgs,
respectively.

Use the Graphics property of the PrintPageEventArgs object obtained from the PrintDocument.PrintPage
event to specify the output to print. If you are printing a text file, use StreamReader to read one line at a
time from the stream and call the DrawString method to draw the line in the graphics object.

Note
The DrawText methods of the TextRenderer class are not supported for printing. Instead, use the
DrawString methods of the Graphics class.

When implemented in a derived class, the PrintController controls how a PrintDocument is printed. The
PrintDocument.Print method invokes the print controller's OnStartPrint, OnEndPrint, OnStartPage, and
OnEndPage methods, which in turn tell the printer how to print the document.

The print-preview process uses a specialized print controller, dialog box, and control. For an example of
such a print controller and dialog box, see PreviewPrintController, PrintPreviewDialog, and
PrintPreviewControl.
Printing from Windows Forms is a document-centric, event-driven process. The bulk of your effort will go
into either using a generic PrintDocument object or implementing a derived PrintDocument class.
Inheriting from the base PrintDocument class is the better way to go—for reasons which I'll go into
shortly. Nevertheless, at times it may be quicker and simpler to use an instance of the base
PrintDocument class.

Printing with a base PrintDocument class requires you to wire the class's PrintPage event to a handler
method (static or instance) whose signature matches the PrintPageEventHandler delegate. This event will
fire when your code calls the Print method on an instance of a PrintDocument object. To actually draw
your page, you use the Graphics property of the PrintPageEventArgs object. An instance of a
PrintPageEventArgs class is passed as an argument to the PrintPage event handler. The Graphics property
of the PrintPageEventArgs object exposes a GDI+ object that encapsulates the drawing surface onto which
you paint your page. (I'll cover some of the basic GDI+ commands later in the article.) To print more than
one page, you notify the underlying print controller that you have more to print. You can do this using the
HasMorePages property of the PrintPageEventArgs object. Setting the HasMorePages property to true will
ensure that your PrintPage event handler gets called again.

In addition, you can set up event handlers for other common print events such as BeginPrint, EndPrint,
and QueryPageSettings. BeginPrint is a good place to initialize any objects (such as Fonts) that your
PrintPage routine may rely on. The QueryPageSettings event fires immediately before each PrintPage
event. It allows you to print each page using different page settings, which you can do by modifying the
QueryPageSettingsEventArgs.PageSettings property. In order to modify page settings for the entire
document, you can use the DefaultPageSettings property of the PrintDocument class.

Copy Code
PrintDocument printDoc = new PrintDocument();
printDoc.PrintPage += new PrintPageEventHandler(this.printDoc_PrintPage);
printDoc.Print();

// The PrintPage event is raised for each page to be printed.


private void printDoc_PrintPage(object sender, PrintPageEventArgs e)
{
// TODO: Print your page using the e.Graphics GDI+ object
// Notify the PrintController whether there are any more pages
e.HasMorePages = false;
}

As you can see, there are numerous drawbacks to this approach. The biggest drawback is that you must
maintain state-aware objects between subsequent calls to the PrintPage event handler. For example, if
you're printing a text document you will need to hold onto an open StreamReader object. You could
initialize the StreamReader during the BeginPrint event and then close it during the EndPrint event. No
matter how you slice it, however, the StreamReader variable will need to be scoped outside of the
PrintPage event handler along with your other variables. When this happens, your printing code is
exposed and vulnerable and can muddy up the rest of your code.

The PrintController Class


Earlier, I mentioned how the sample printing application (shown in Figure 1) allows you to display an
optional status dialog and/or animated status bar icon (the kind that spits out pages while printing). Both
of these features are implemented using derived print controller classes. PrintController is an abstract
class that is implemented by three different concrete classes within the .NET Framework:
StandardPrintController, PrintControllerWithStatusDialog, and PreviewPrintController.
The print controller is responsible for how a print document is printed. The PrintDocument class exposes
its underlying print controller as a property. Calling a print document's Print method triggers the
underlying print controller's OnStartPrint, OnEndPrint, OnStartPage, and OnEndPage methods. Figure 3
shows the sequence of events that occur between the print document and the print controller.
OnStartPage is the only method that returns a value. The return value is of type Graphics and, as you
may have already guessed, is the GDI+ drawing surface that is passed to the print document via the
PrintPageEventArgs argument.

Figure 3 Print Flow

The default print controller is of type PrintControllerWithStatusDialog. So, if you want to turn off the print
status dialog, you'll need to use the StandardPrintController. The PreviewPrintController is used by the
PrintPreviewDialog and PrintPreviewControl classes. PrintControllerWithStatusDialog can be found in the
System.Windows.Forms namespace, while StandardPrintController and PreviewPrintController are located
under the System.Drawing.Printing namespace. The PrintControllerWithStatusDialog provides an
overloaded constructor that takes another print controller as an argument. This allows you to combine the
PrintControllerWithStatusDialog with any additional features that you might add to your own print
controller. When running the sample printing application, try checking both the
PrintControllerWithStatusDialog and PrintControllerWithStatusBar checkboxes to see this in action
PrintController.OnStartPrint Method

OnStartPrint is called immediately after the PrintDocument raises the BeginPrint event.

Use the OnStartPrint method to determine when and how to print a document. For example, you can
delay printing for 30 minutes or adjust the printer settings for the document. OnStartPrint creates the
Graphics that is sent to the printer. After OnStartPrint is called, the OnStartPage method sets the Graphics
to one of a single page. The OnEndPage method clears the Graphics, while the OnEndPrint method
deallocates the object.

The OnStartPrint method is a good place to verify that PrinterSettings are valid.

PrintController.OnStartPage Method

OnStartPage is called immediately before the PrintDocument raises the PrintPage event.

OnStartPrint creates the Graphics that is sent to the printer. After OnStartPrint is called, the OnStartPage
method sets the Graphics to a graphic of a single page. The OnEndPage method clears the Graphics, while
the OnEndPrint method deallocates the object.

Use the OnStartPage method to set how to print a page in a document. For example, you can adjust page
settings separately for each page.

PrintController.OnEndPage Method

OnEndPage is called immediately after the PrintDocument raises the PrintPage event. If an exception is
thrown inside a PrintPage event of a PrintDocument, OnEndPage is not called.

OnStartPrint creates the Graphics that is sent to the printer. After OnStartPrint is called, the OnStartPage
method sets the Graphics to a graphic of a single page. (Use the OnStartPage method to set how to print
a page in a document. For example, you can adjust page settings separately for each page.) The
OnEndPage method clears the Graphics, while the OnEndPrint method deallocates the object.

PrintController.OnEndPrint Method

OnEndPrint is called immediately after the PrintDocument raises the EndPrint event.

OnStartPrint creates the Graphics that is sent to the printer. After OnStartPrint is called, the OnStartPage
method sets the Graphics to a graphic of a single page. (Use the OnStartPrint method to determine when
and how to print a document. For example, you can delay printing for 30 minutes or adjust the printer
settings for the document.) The OnEndPage method clears the Graphics, while the OnEndPrint method
deallocates the object

You might also like