Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Manning - Windows Forms Programming With CSharp.pdf
Скачиваний:
72
Добавлен:
24.05.2014
Размер:
14.98 Mб
Скачать

While this may not be the prettiest image printing application, it does demonstrate some important principles, such as using the page margins and text wrapping. We will present the changes in two parts, one for each of our ParentForm and MainForm objects.

18.1.1USING THE PRINT CLASSES

The parent form will make direct use of the print classes previously mentioned, contain the menu items for printing, and maintain the required PrintDocument object. Placing the print document on the parent form ensures that any changes made to the page margins or other document settings are seen by all child forms in the application.

The following tables detail the changes required on the parent form.

Set the version number for the MyPhotos application to 18.1.

MODIFY PARENT FORM TO SUPPORT PRINT MENUS

 

 

 

 

 

Action

 

 

 

Result

 

 

 

 

 

 

 

 

 

 

1

In the ParentForm.cs [Design] window, add

 

 

three menus and a separator to the File

 

 

menu.

 

 

 

 

 

 

 

 

 

 

 

 

 

Settings

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Menu

 

Property

 

Value

 

 

 

separator

 

MergeOrder

 

6

 

 

 

 

 

Page

 

(Name)

 

menuPageSetup

 

 

 

Setup

 

MergeOrder

 

7

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Text

 

Page Set&up…

 

 

 

Print

 

(Name)

 

menuPrintPreview

 

 

 

Preview

 

MergeOrder

 

7

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Text

 

Print Pre&view

 

 

 

Print

 

(Name)

 

menuPrint

 

 

 

 

 

 

MergeOrder

 

7

 

 

 

 

 

 

 

 

Shortcut

 

CtrlP

 

 

 

 

 

 

Text

 

&Print…

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2

Also drag a PrintDocument object onto the

 

 

form.

 

 

 

 

 

 

 

 

 

 

 

 

 

Settings

 

 

 

 

 

 

 

 

 

 

 

Property

 

 

Value

 

 

 

 

 

(Name)

 

printDoc

 

 

 

 

DocumentName

Image Document

 

 

The object appears in the component tray of

 

 

the designer window.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

PRINTING

605

These menus provides the necessary user interface support. Next we hook up our three print menus in the ParentForm class.

HANDLE PRINT RELATED MENUS IN PARENT FORM

 

Action

Result

 

 

 

3

Add a Click event handler for the

private void menuPageSetup_Click

 

Page Setup menu to display a

(object sender, System.EventArgs e)

 

PageSetupDialog window for the

{

 

PageSetupDialog dlg

 

form’s print document.

 

= new PageSetupDialog();

 

 

dlg.Document = printDoc;

 

 

dlg.ShowDialog();

 

 

}

 

 

 

4

Add a Click event handler for the

private void menuPrintPreview_Click

 

Print Preview menu to display a

(object sender, System.EventArgs e)

 

PrintPreviewDialog window for

{

 

PrintPreviewDialog dlg

 

the form’s print document.

 

= new PrintPreviewDialog();

 

Note: The PrintPreviewDialog

dlg.Document = printDoc;

 

dlg.ShowDialog();

 

window displays the document to

 

}

 

be printed within a PrintPreview-

 

 

Control object contained within

 

 

the preview window.

 

 

 

 

5

Add a Click event handler for the

private void menuPrint_Click

 

Print menu to display a PrintDialog

(object sender, System.EventArgs e)

 

window for the form’s print

{

 

PrintDialog dlg = new PrintDialog();

 

document.

 

dlg.Document = printDoc;

 

Note: The common print dialog

if (dlg.ShowDialog() == DialogResult.OK)

 

{

 

allows the user to select standard

 

printDoc.Print();

 

settings such as which printer to use

}

 

and the number of copies to make.

}

 

If the user clicks the OK button, then

 

 

we invoke the Print method in the

 

 

PrintDocument class to initiate the

 

 

actual print operation.

 

 

 

 

6

Handle the PrintPage event for the

private void printDoc_PrintPage

 

PrintDocument object on the parent

(object sender, System.Drawing.

 

form.

Printing.PrintPageEventArgs e)

 

{

 

 

 

Note: This event occurs for each

 

 

page to be printed. The BeginPrint

 

 

and EndPrint events occur at the

 

 

start and end of the entire print

 

 

operation, respectively.

 

 

 

 

7

In this handler:

MainForm f = ActiveMdiChild as MainForm;

 

a. If the active child is a MainForm

if (f != null)

 

f.PrintCurrentImage(e);

 

object, call the yet-to-be-written

else

 

PrintCurrentImage method on

e.Cancel = true;

 

this object.

}

 

 

 

b. Otherwise, cancel the print

 

 

operation.

 

 

 

 

606

CHAPTER 18 ODDS AND ENDS .NET

These event handlers establish the required printing support for the parent form. The printing logic for the child form is presented next.

18.1.2DRAWING A PRINT PAGE

With our user interface logic in place, we are ready to implement the printing of a page. This is done using the PrintPageEventArgs parameter provided to the PrintPage event handler. This class is summarized in .NET Table 18.1.

.NET Table 18.1 PrintPageEventArgs class

The PrintPageEventArgs class represents an event argument containing information required for printing pages to a printer. This class is part of the System.Drawing.Printing namespace, and inherits from the System.EventArgs class.

 

Cancel

Gets or sets whether the print job should be

 

 

cancelled.

 

Graphics

Gets the Graphics object on which to paint the

 

 

page to print.

 

HasMorePages

Gets or sets whether an additional page should

 

 

be printed after the current one.

Public Properties

 

 

 

MarginBounds

Gets the printable area of a page, which is the

 

 

rectangle within the margins of the page.

 

PageBounds

Gets the page area, which is the rectangle

 

 

representing the entire page.

 

PageSettings

Gets the PageSettings object representing the

 

 

settings for the current page.

 

 

 

We will implement a PrintCurrentImage method in the MainForm class to make use of this parameter. Internally, this will draw the photograph using the provided Graphics object, and use an internal PrintTextString method to draw the individual properties for the photograph.

IMPLEMENT THE PRINTCURRENTIMAGE METHOD

 

Action

Result

 

 

 

1

In the MainForm.cs code

using System.Drawing.Printing;

 

window, indicate that we will

 

 

use members of the

 

 

System.Drawing.Printing

 

 

namespace.

 

 

 

 

2

Add a PrintCurrentImage

public void PrintCurrentImage

 

method that accepts a

(PrintPageEventArgs e)

 

PrintPageEventArgs object as

{

 

 

 

a parameter.

 

 

 

 

PRINTING

607

IMPLEMENT THE PRINTCURRENTIMAGE METHOD (continued)

 

Action

Result

 

 

 

3

If there is no current photo, then

Photograph photo = _album.CurrentPhoto;

 

abort the print operation.

if (photo == null)

 

 

{

 

 

// nothing to print, so abort

 

 

e.Cancel = true;

 

 

return;

 

 

}

 

 

 

4

Otherwise, create some

// Establish some useful shortcuts

 

shortcuts for the margins of the

float leftMargin = e.MarginBounds.Left;

 

page and the Graphics object.

float rightMargin = e.MarginBounds.Right;

 

float topMargin = e.MarginBounds.Top;

 

 

 

 

float bottomMargin

 

 

= e.MarginBounds.Bottom;

 

 

float printableWidth = e.MarginBounds.Width;

 

 

float printableHeight

 

 

= e.MarginBounds.Height;

 

 

Graphics g = e.Graphics;

 

 

 

5

Create a Font object:

Font printFont

 

a. Use 11 point Times New

= new Font("Times New Roman", 11);

 

float fontHeight = printFont.GetHeight(g);

 

Roman.

float spaceWidth = g.MeasureString(" ",

 

b. Use the GetHeight method

printFont).Width;

 

 

 

to determine the height of

 

 

each line of text.

 

 

c. Use the MeasureString

 

 

method to determine the size

 

 

of a space.

 

 

 

 

6

Determine the correct length so

// Draw image in box 75% of shortest side

 

that the image can be drawn

float imageBoxLength;

 

into a box which is 75% of the

float xPos = leftMargin;

 

float yPos = topMargin + fontHeight;

 

shortest side of the page.

 

if (printableWidth < printableHeight)

 

Note: This logic accounts for

{

 

imageBoxLength = printableWidth * 75/100;

 

both landscape and portrait

 

yPos += imageBoxLength;

 

page orientation. The xPos and

}

 

yPos variables represent where

else

 

the first line of text should be

{

 

imageBoxLength = printableHeight * 75/100;

 

drawn.

 

xPos += imageBoxLength + spaceWidth;

 

 

}

 

 

 

7

Draw the image into a box of the

// Draw image at start of the page

 

determined size.

Rectangle imageBox

 

 

= new Rectangle((int)leftMargin + 1,

 

 

(int)topMargin + 1,

 

 

(int)imageBoxLength,

 

 

(int)imageBoxLength);

 

 

g.DrawImage(photo.Image,

 

 

photo.ScaleToFit(imageBox));

 

 

 

8

Determine the RectangleF

// Determine rectangle for text

 

object where all text should be

RectangleF printArea

 

drawn.

= new RectangleF(xPos, yPos,

 

rightMargin - xPos,

 

 

 

 

bottomMargin - yPos);

 

 

 

608

CHAPTER 18 ODDS AND ENDS .NET