8.14 Print a Multipage Document


Problem

You need to print complex documents with multiple pages and possibly print several different documents at once.

Solution

Place the information you want to print into a custom class that derives from PrintDocument , and set the PrintPageEventArgs.HasMorePages property to true as long as there are pages remaining.

Discussion

The PrintDocument.PrintPage event allows you to print only a single page. If you need to print more pages, you need to set the PrintPageEventArgs.HasMorePages property to true in the PrintPage event handler. As long as HasMorePages is true , the PrintDocument class will continue firing PrintPage events, one for each page. However, it's up to you to track what page you are on, what data should be placed on each page, and so on. To facilitate this tracking, it's a good idea to create a custom class.

The following example shows a class called TextDocument . This class inherits from PrintDocument and adds three properties. Text stores an array of text lines, PageNumber reflects the last printed page, and Offset indicates the last line that was printed from the Text array.

 public class TextDocument : PrintDocument {     private string[] text;     private int pageNumber;     private int offset;     public string[] Text {         get {return text;}         set {text = value;}     }     public int PageNumber {         get {return pageNumber;}         set {pageNumber = value;}     }     public int Offset {         get {return offset;}         set {offset = value;}     }     public TextDocument(string[] text) {         this.Text = text;     } } 

Depending on the type of material you are printing, you might want to modify this class. For example, you could store an array of image data, some content that should be used as a header or footer on each page, font information, or even the name of a file from which you want to read the information. Encapsulating the information in a single class makes it easier to print more than one document at the same time.

The code that initiates printing is the same as in recipe 8.13, only now it creates a TextDocument instance instead of a PrintDocument instance. The PrintPage event handler keeps track of the current line and checks if there is space on the page before attempting to print the next line. If a new page is needed, the HasMorePages property is set to true and the PrintPage event fires again for the next page. If not, the print operation is deemed complete.

The full form code is shown here:

 using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Printing; public class MultiPagePrint : System.Windows.Forms.Form {     private System.Windows.Forms.Button cmdPrint;     // (Designer code omitted.)     private void cmdPrint_Click(object sender, System.EventArgs e) {              // Create a document with 100 lines.         string[] printText = new string[101];         for (int i=0; i < 101; i++) {                      printText[i] = i.ToString();             printText[i] += ": The quick brown fox jumps over the lazy dog.";         }         PrintDocument doc = new TextDocument(printText);         doc.PrintPage += new PrintPageEventHandler(this.Doc_PrintPage);         PrintDialog dlgSettings = new PrintDialog();         dlgSettings.Document = doc;         // If the user clicked OK, print the document.         if (dlgSettings.ShowDialog() == DialogResult.OK) {             doc.Print();         }     }     private void Doc_PrintPage(object sender, PrintPageEventArgs e) {              // Retrieve the document that sent this event.         TextDocument doc = (TextDocument)sender;                     // Define the font and determine the line height.         Font font = new Font("Arial", 10);         float lineHeight = font.GetHeight(e.Graphics);         // Create variables to hold position on page.         float x = e.MarginBounds.Left;         float y = e.MarginBounds.Top;         // Increment the page counter (to reflect the page that is about to be          // printed).         doc.PageNumber += 1;         // Print all the information that can fit on the page.                 // This loop ends when the next line would go over the margin bounds,         // or there are no more lines to print.         while ((y + lineHeight) < e.MarginBounds.Bottom &&           doc.Offset <= doc.Text.GetUpperBound(0)) {                      e.Graphics.DrawString(doc.Text[doc.Offset], font,                Brushes.Black, x, y);             // Move to the next line of data.             doc.Offset += 1;             // Move the equivalent of one line down the page.             y += lineHeight;         }                      if (doc.Offset < doc.Text.GetUpperBound(0)) {                      // There is still at least one more page.             // Signal this event to fire again.             e.HasMorePages = true;         }else {                      // Printing is complete.             doc.Offset = 0;         }     } } 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net