The PrintDocument and Print Events

So far we have seen how to print simple text and how to read and set printer settings. In the previous sections we saw that in a printing application, we create a PrintDocument object, set its printer name, set the printpage event handler, and then call the Print method. PrintDocument offers more than this. In this section we will cover PrintDocument members and print events.

The PrintDocument class is used to tell the printing system how printing will take place. Table 11.4 describes the properties of the PrintDocument class.

Besides the properties described in Table 11.4, PrintDocument also provides printing-related methods that invoke print events. These methods are described in Table 11.5.

Table 11.4. PrintDocument properties

Property

Description

DefaultPageSettings

Represents the page settings using a PageSettings object.

DocumentName

Returns the name of the document to be displayed in a print status dialog box or printer queue while printing the document.

PrintController

Returns the print controller that guides the printing process.

PrinterSettings

Returns the printer settings represented by a PrinterSettings object.

Table 11.5. PrintDocument methods

Method

Description

OnBeginPrint

Raises the BeginPrint event, which is called after the Print method and before the first page of the document is printed.

OnEndPrint

Raises the EndPrint event, which is called when the last page of the document has been printed.

OnPrintPage

Raises the PrintPage event, which is called before a page prints.

OnQueryPageSettings

Raises the QueryPageSettings event, which is called immediately before each PrintPage event.

Print

Starts the document's printing process.

All of these methods allow derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class. We will discuss these methods and their events, and how to handle them, in our examples.

11.5.1 Understanding Print Events

During the printing process, the printing system fires events according to the stage of a printing process. The three common events are BeginPrint, PrintPage, and EndPrint. As their names indicate, the BeginPrint event occurs when the Print method is called, and the EndPrint event occurs when the last page of the document has been printed. The PrintPage event occurs for each page being printed (as in Figure 11.10) when the Print method is called and after the BeginPrint event has occurred.

Figure 11.10. Print events

Figure 11.10 shows a flowchart for the print events during a printing process. The BeginPrint event is raised after the Print method is called. Then the printing process checks if there are any pages. If there are, the PrintPage event occurs, which is responsible for the actual printing, and the control goes back to check if there are more pages to print. When all pages are done printing, the EndPage event is fired.

The PrintEventArgs class provides data for BeginPrint and EndPrint events. This class is inherited from CancelEventArgs, which implements a single property called Cancel, that indicates if an event should be canceled (in the current .NET Framework release, PrintEventArgs is reserved for future use).

The BeginPrint event occurs when the Print method is called and before the first page prints. BeginPrint takes a PrintEventArgs object as an argument. This event is the best place to initialize resources. The PrintEventHandler method, which is used to handle the event code, is called whenever the BeginPrint event occurs.

The PrintPage event occurs when the Print method is called and before a page prints. When we create a PrintPageEventHandler delegate, we identify a method that handles the PrintPage event. The event handler is called whenever the PrintPage event occurs.

The code snippet that follows creates a PrintPageEventHandler delegate, where pd_PrintPage is an event handler:

 

PrintDocument pd = new PrintDocument(); pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);

 

PrintPageEventHandler takes a PrintPageEventArgs object as its second argument, which has the six properties described in Table 11.6.

The following code snippet shows how to get the Graphics object from PrintPageEventArgs:

 

public void pd_PrintPage(object sender, PrintPageEventArgs ev) { // Get the Graphics object attached to // PrintPageEventArgs Graphics g = ev.Graphics; // Use g now }

 

The EndPrint event occurs when the last page of the document has been printed. It takes a PrintEventArgs object as an argument. This is the best place to free your resources. The PrintEventHandler method is called whenever the EndPrint event occurs and is used to handle the event code.

Now let's write an application that shows how to use these events. We create a Windows application and add a a combo box and a button to the form. We set ComboBox.Name to printersList and the text of the button to PrintEvents Start. The final form looks like Figure 11.11.

Figure 11.11. The print events application

Table 11.6. PrintPageEventArgs properties

Property

Description

Cancel

Indicates whether the print job should be canceled. Both get and set.

Graphics

Returns the Graphics object.

HasMorePages

Indicates whether an additional page should be printed. Used in multipage documents before the Print method is called. Both get and set.

MarginBounds

Returns the portion of the page inside the margins.

PageBounds

Returns the total area of the page.

PageSettings

Returns page settings for the current page.

Next we add a reference to the System.Drawing.Printing namespace as follows:

 

using System.Drawing.Printing;

 

Then we add code on the form's load event handler that adds all installed printers to the combo box (see Listing 11.18).

Listing 11.18 Loading all installed printers

private void Form1_Load(object sender, System.EventArgs e) { // See if any printers are installed if( PrinterSettings.InstalledPrinters.Count <= 0) { MessageBox.Show("Printer not found!"); return; } // Get all available printers and add them to the // combo box foreach(String printer in PrinterSettings.InstalledPrinters) { printersList.Items.Add(printer.ToString()); } }

Now we write code for the button click event handler. Listing 11.19 creates all three print event handlers, attaches them to a PrintDocument object, and calls PrintDocument's print methods.

Listing 11.19 Attaching BeginPrint, EndPrint, and PagePrint event handlers

private void PrintEvents_Click(object sender, System.EventArgs e) { // Get the selected printer string printerName = printersList.SelectedItem.ToString(); // Create a PrintDocument object and set the // current printer PrintDocument pd = new PrintDocument(); pd.PrinterSettings.PrinterName = printerName; // BeginPrint event pd.BeginPrint += new PrintEventHandler(BgnPrntEventHandler); // PrintPage event pd.PrintPage += new PrintPageEventHandler(PrntPgEventHandler); // EndPrint event pd.EndPrint += new PrintEventHandler(EndPrntEventHandler); // Print the document pd.Print(); }

As stated earlier, the BeginPrint event handler can be used to initialize resources before printing starts, and the EndPrint event handler can be used to free allocated resources. Listing 11.20 shows all three print event handlers. The PrintPage event handler uses the properties for PrintPageEventArgs and calls DrawRectangle and FillRectangle to print the rectangles. This example simply shows how to call these events. You can use the PrintPage event handler to draw anything you want to print, as we have seen in previous examples.

Listing 11.20 The BeginPrint, EndPrint, and PagePrint event handlers

public void BgnPrntEventHandler(object sender, PrintEventArgs peaArgs) { // Create a brush and a pen redBrush = new SolidBrush(Color.Red); bluePen = new Pen(Color.Blue, 3); } public void EndPrntEventHandler(object sender, PrintEventArgs peaArgs) { // Release brush and pen objects redBrush.Dispose(); bluePen.Dispose(); } public void PrntPgEventHandler(object sender, PrintPageEventArgs ppeArgs) { // Create PrinterSettings object PrinterSettings ps = new PrinterSettings(); // Get Graphics object Graphics g = ppeArgs.Graphics; // Create PageSettings object PageSettings pgSettings = new PageSettings(ps); // Set page margins ppeArgs.PageSettings.Margins.Left = 50; ppeArgs.PageSettings.Margins.Right = 100; ppeArgs.PageSettings.Margins.Top = 50; ppeArgs.PageSettings.Margins.Bottom = 100; // Create two rectangles Rectangle rect1 = new Rectangle(20, 20, 50, 50); Rectangle rect2 = new Rectangle(100, 100, 50, 100); // Draw and fill rectangles g.DrawRectangle(bluePen, rect1); g.FillRectangle(redBrush, rect2); }

As this discussion has shown, the print event can be handy when you need to initialize or free resources.

Категории