C#  â€¢  PrintPage Provides the Key to Printing

Listing 5. The PrintPage event is the primary event you'll use when printing using the System.Drawing.Printing objects. This event fires once per page until you set the value of ev.HasMorePages to false. The code used to retrieve the hard margins makes up for any shortcomings in the .NET Framework.

private void doc_PrintPage(object sender, 
   System.Drawing.Printing.PrintPageEventArgs ev) {
   _currentPage++;
   String headerText = "Northwinds Customer Contacts";
   IntPtr hDc = ev.Graphics.GetHdc();
   ev.Graphics.ReleaseHdc(hDc);
   marginInfo mi = new marginInfo(hDc.ToInt32());
   // take the hard margins into account…
   float leftMargin = ev.MarginBounds.Left - mi.Left;
   float rightMargin = ev.MarginBounds.Right;
   float topMargin = ev.MarginBounds.Top - mi.Left;
   float bottomMargin = ev.MarginBounds.Bottom;
   float pageHeight = bottomMargin - topMargin;
   float pageWidth = rightMargin - leftMargin;
   float headerHeight = 
   headerFont.GetHeight(ev.Graphics);
   float footerHeight = bodyFont.GetHeight(ev.Graphics);
   // report header
   RectangleF ReportheaderR = new RectangleF(leftMargin, 
      topMargin, pageWidth, headerHeight);
   // report body
   RectangleF bodyR = new RectangleF(leftMargin, 
      ReportheaderR.Bottom, pageWidth, pageHeight - 
      ReportheaderR.Height - footerHeight);            
   // report footer
   RectangleF ReportfooterR = new RectangleF(leftMargin, 
      bodyR.Bottom, pageWidth, footerHeight * 2);
   // results of using the Split function on the text
   String[] el;
   // a line of text from our file
   string text = "";
   // print the header once per page
   centerText(ev.Graphics, headerText, headerFont, 
      defaultBrush, ReportheaderR);
   // the header is equal to 2 normal lines
   int currentLine = 2;
   // how many lines can we fit on a page?              
   int linesPerPage = Convert.ToInt32(bodyR.Height / 
      bodyFont.GetHeight(ev.Graphics)) - 1;
   float bodyFontHeight = 
      bodyFont.GetHeight(ev.Graphics);
   float currentY;
   // Print each line of the file.
   while(currentLine < linesPerPage && 
   ((text=data.ReadLine()) != null)) {
      el = text.Split(',');
      currentY = getCurrentY(currentLine, topMargin, 
         bodyFontHeight);
      ev.Graphics.DrawString(el[0], bodyFont, 
         defaultBrush, bodyR.Left, currentY);
      currentLine++;
      currentY = getCurrentY(currentLine, topMargin, 
         bodyFontHeight);
      ev.Graphics.DrawString(el[1], 
         bodyFont, defaultBrush, bodyR.Left + 20, 
         currentY);
      currentLine++;
      currentY = getCurrentY(currentLine, topMargin, 
         bodyFontHeight);
      ev.Graphics.DrawString("Phone: " + el[2], 
         bodyFont, defaultBrush, bodyR.Left + 20, 
         currentY);
      currentLine++;
      currentY = getCurrentY(currentLine, topMargin, 
         bodyFontHeight);
      ev.Graphics.DrawString("Fax: " + el[3],
         bodyFont,defaultBrush, bodyR.Left + 20, 
         currentY);
      currentLine++;
      currentY = getCurrentY(currentLine, topMargin, 
         bodyFontHeight);
      ev.Graphics.DrawLine(Pens.Black, leftMargin, 
         currentY, ev.MarginBounds.Right, currentY);
   }
   // page number
   centerText(ev.Graphics, "Page " + 
      currentPage.ToString(), bodyFont, 
      defaultBrush, ReportfooterR);
   if (text != null) {
      ev.HasMorePages = true;
   } else {
      // no more pages to print
      ev.HasMorePages = false;
   }
}
private float getCurrentY(int currentLine, float 
   topMargin, float fontHeight) {
   return topMargin + (currentLine * fontHeight);
}
private void centerText(Graphics g, 
   string t, Font f, Brush b, RectangleF 
   rect) {
   StringFormat sf = new StringFormat();
   sf.Alignment = 
      StringAlignment.Center;
   g.DrawString(t, f, b, rect, sf);
}