: C# 2008 Programmer

Adding Print Support to the Project

Adding Print Support to the Project

To add print support to the PhotoViewer application, first add the controls (see Figure 16-14) in the following table.

Control Text Name
Label controls (2) Print from:
TextBox controls (2) txtFrom
Button controls (2) Preview btnPreview
Print btnPrint

Figure 16-14

Switch to the code-behind of Form1, and import the following namespace:

using System.Drawing.Printing;

Declare the following member variables:

public partial class Form1 : Form {
//---constants for the icon images---
const int ico_OPEN = 0;
const int ico_CLOSE = 1;
const int ico_PHOTO = 2;
//---font variables---
Font f_title;
Font f_body;
//---page counter---
int pagecounter;
//---PrintDocument variable---
PrintDocument printDoc;

When the form is loaded during runtime, create an instance of the PrintDocument class, and wire up the three main event handlers described earlier:

private void Form1_Load(object sender, EventArgs e) {
printDoc = new PrintDocument() {
DocumentName = "Printing from Photo Viewer"
printDoc.BeginPrint += new PrintEventHandler(printDoc_BeginPrint);
printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
printDoc.EndPrint += new PrintEventHandler(printDoc_EndPrint);
try {
//---load the application settings values
// into the textbox controls---

In the event handler for the BeginPrint event, initialize the page counter as well as the fonts of the text to be used for printing the page:

void printDoc_BeginPrint(object sender, PrintEventArgs e) {
//---initialize the page counter---
pagecounter = int.Parse(txtFrom.Text);
//---initialize the fonts---
f_title = new Font("Arial", 16, FontStyle.Bold);
f_body = new Font("Times New Roman", 10);

In the EndPrint event handler, dereference the font variables used:

void printDoc_EndPrint(object sender, PrintEventArgs e) {
//---de-reference the fonts---
f_title = null;
f_body = null;

Finally, the event handler for PrintPage is the place where you do the bulk of the work of sending the output to the printer. Basically, you use the Graphics object in the PrintPageEventArgs class to specify the output you want to print. For example, to draw a rectangle you would use the e.Graphics.DrawRectangle() method (where e is an instance of the PrintPageEventArgs class). To print a string, you use the e.Graphics.DrawString() method. After printing, you increment the page count and determine if there are any more pages to print. If there are, setting the HasMorePages property of the PrintPageEventArgs class to true will cause the printDoc_PrintPage event handler fire one more time. Once there are no more pages left to print, set the HasMorePages property to false:

void printDoc_PrintPage(object sender, PrintPageEventArgs e) {
Graphics g = e.Graphics; //---draws the title---
g.DrawString(TreeView1.SelectedNode.Text, f_title, Brushes.Black, 20, 30);
//---draws a border...---
Rectangle border =
new Rectangle(10, 10,
PictureBox1.Width + 20, PictureBox1.Height + 60);
//---...using a thick pen---
Pen thickPen = new Pen(Color.Black, 3);
g.DrawRectangle(thickPen, border);
//---draws the picture---
if (PictureBox1.Image != null) {
g.DrawImage(PictureBox1.Image, 20, 60,
//---draws the page count---
g.DrawString("Page " + pagecounter, f_body, Brushes.Black, 20, 420);
//---increments the page counter---
pagecounter += 1;
//---determine if you have more pages to print---
if (pagecounter <= int.Parse(txtTo.Text)) e.HasMorePages = true;
else e.HasMorePages = false;

To let the user preview the output before the image is sent to the printer for printing, use the PrintPreviewDialog() class:

private void btnPreview_Click(object sender, EventArgs e) {
//---show preview---
PrintPreviewDialog dlg = new PrintPreviewDialog() {
Document = printDoc

This code previews the output in a separate window (see Figure 16-15). The user can click the printer icon to send the output to the printer. The user can also choose to enlarge the page or view multiple pages on one single screen.

Figure 16-15

To print the image to a printer, use the PrintDialog class to let the user choose the desired printer (see Figure 16-16) instead of sending the output directly to the default printer:

private void btnPrint_Click(object sender, EventArgs e) {
//---let user select a printer to print---
PrintDialog pd = new PrintDialog() {
Document = printDoc, AllowSomePages = true
DialogResult result = pd.ShowDialog();
if (result == DialogResult.OK) printDoc.Print();

Figure 16-16

Figure16-17 shows the output if the user indicated that he wanted to print from page 1 to 3 (in Form1). Note the page number displayed below the image.

Figure 16-17

: 1.166. /Cache: 3 / 1