Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# ПІДРУЧНИКИ / c# / Manning - Windows.forms.programming.with.c#.pdf
Скачиваний:
108
Добавлен:
12.02.2016
Размер:
14.98 Mб
Скачать
OnRe-

The code also sets the InitialDirectory property to the current directory using the Environment class. This ensures that the initial directory in the dialog is always the current directory for our application. While this may not seem so relevant right now, it will become important when we implement Click handlers for our Save and Save As menus. We will look at the Environment class in more detail later in the chapter.

The menuAdd_Click method is similar to our original Load menu handler, but also very different. In particular, this method leaves unresolved the issue of what to display in the form, and the exception handling has been removed. We will handle these issues subsequently. For now, let’s move on to the Remove menu handler.

6.2.2REMOVING IMAGES FROM AN ALBUM

The event handler for the Remove menu uses the CurrentPosition property to locate the current photo and delete it from the album.

 

 

IMPLEMENT REMOVE HANDLER

 

 

 

 

 

Action

 

Result

 

 

 

 

1

Add a Click handler for

 

protected void menuRemove_Click

 

the Remove menu.

 

(object sender, System.EventArgs e)

 

 

 

{

 

 

 

 

2

Implement this handler to

 

if (_album.Count > 0)

 

remove the current photo

 

{

 

from the album.

 

_album.RemoveAt(_album.CurrentPosition);

 

 

_bAlbumChanged = true;

 

 

 

 

 

 

}

 

 

 

this.Invalidate();

 

 

 

}

 

 

 

 

The menuRemove_Click handler uses the RemoveAt method from our PhotoAlbum class to remove the current photo. The issue of adjusting the current position in case we remove the last photo from the album is left to the PhotoAlbum class to handle. If you recall, the RemoveAt method we implemented in chapter 5 ensures that the current index remains valid after it is called through an override of the moveComplete method, so the current position is properly updated here.

Once again we have ignored the display issues. This is because our menu handlers will no longer interact with the Form window directly. Instead we will override the protected OnPaint method for this purpose, which is our next topic.

6.3PAINT EVENTS

Now that we can load multiple images into our album, we need a way to make them appear in the window. In previous chapters, we have simply assigned the selected photo to the Image property of our PictureBox control and relied on the .NET Framework to deal with the rest. The framework will still do most of the work, but now we need to identify which image from our album should be drawn.

PAINT EVENTS

169

As in previous Microsoft development environments, such drawing is called painting in .NET. You may have noticed in chapter 3 that the Control class provides a Paint event for custom painting of a control. The event name is one piece of the support provided for each event in the .NET Framework. While we have seen these pieces in our previous use of events, this is a good place to list them more formally. The following support is required in order to define and support an event.

A class that defines the event data. This is either the System.EventArgs class or a class derived from System.EventArgs. The event data for the Paint event is defined by the PaintEventArgs class. We will discuss the contents of the PaintEventArgs class in chapter 7.

A delegate for the event. This delegate is used by Visual Studio .NET to add the event handler in the InitializeComponent method. By convention, the name of this delegate is the event name followed by the string “EventHandler.” The Paint event is supported by the PaintEventHandler delegate. The creation of delegates is discussed in chapter 9.

A class that raises the event. This class must define the event and provide a method to raise the event. By convention the method to raise the event is the string “On” followed by the event name. The protected OnPaint method raises the Paint event.

For painting of controls, the Control class defines the Paint event. Within the definition of this class, the event is defined using the event keyword in C#.

public event PaintEventHandler Paint;

6.3.1DRAWING THE CURRENT PHOTOGRAPH

Returning to our code, we need a way to draw the appropriate photograph in our album. We could handle the Paint event directly in our Form or PictureBox control for this purpose. Instead, since the MainForm class derives from the Form class, we can override the method that raises the event directly. This technique is preferred where possible to avoid the extra overhead of creating and invoking an event handler. In this case, we will override the protected OnPaint method to handle the Paint event.

170

CHAPTER 6 COMMON FILE DIALOGS

Set the version number of the MyPhotos application to 6.4.

OVERRIDE THE ONPAINT METHOD

 

Action

Result

 

 

 

1

In the MainForm.cs file override the

protected override void OnPaint(

 

OnPaint method.

PaintEventArgs e)

 

 

{

 

 

 

2

Only paint an image if the album is

if (_album.Count > 0)

 

not empty.

{

 

Note: The three comments here

// Paint the current image

 

// Update the status bar

 

are implemented in the subsequent

}

 

steps. In all cases, the status bar is

else

 

{

 

invalidated.

 

// Indicate the album is empty

 

 

}

 

 

statusBar1.Invalidate();

 

 

 

3

Call OnPaint in the base class.

base.OnPaint(e);

 

 

}

 

 

Note: This call is required to ensure that any

 

 

Paint event handlers registered with the Form

 

 

are called. As mentioned in chapter 5, the base

 

 

keyword refers to the base class of the current

 

 

object.

 

 

 

4

Paint the current image by setting

// Paint the current image

 

the Image property of the pbxPhoto

Photograph photo = _album.CurrentPhoto;

 

control.

pbxPhoto.Image = photo.Image;

 

 

 

 

 

5

Update the status bar to hold the

// Update the status bar.

 

appropriate information about the

sbpnlFileName.Text = photo.FileName;

 

image.

sbpnlImageSize.Text = String.Format

 

("{0:#} x {1:#}",

 

 

 

Note: The code here is similar to

photo.Image.Width,

 

what we used in our

photo.Image.Height

 

);

 

menuLoad_Click event handler in

 

statusBar1.ShowPanels = true;

 

chapter 4.

 

 

 

 

6

When no images are present, clear

// Indicate the album is empty

 

the screen and display an

pbxPhoto.Image = null;

 

appropriate status bar message.

statusBar1.Text = "No Photos in Album";

 

 

 

 

statusBar1.ShowPanels = false;

 

 

 

6.3.2DISPLAYING THE CURRENT POSITION

Before we see our changes in action, it would be nice to have some indication of our current position within the album and the total album size in the window. We can do this by adding a new StatusBarPanel to hold this information, as detailed by the following steps.

PAINT EVENTS

171

ADD A NEW STATUS BAR PANEL

 

 

Action

Result

 

 

 

 

 

 

1

In the MainForm.cs Design window,

The StatusBarPanel Collection Editor dialog

 

display the StatusBarPanel Collection

appears as was shown in chapter 4.

 

Editor for the statusBar1 control.

 

 

How-to

 

 

 

 

a. Display the properties for this control.

 

 

b. Click on the Panels property item.

 

 

c. Click the button.

 

 

 

 

 

 

 

2

Add a new StatusBarPanel in this

The new panel is added to the Panels collection.

 

dialog just before the existing

The source code in the InitializeComponent

 

sbpnlImagePercent panel.

method is updated to define the new panel and

 

How-to

 

 

add it to the status bar.

 

 

 

 

 

a. Click the Add button.

 

 

b. Click the up arrow in the center of

 

 

the dialog to move the panel just

 

 

beforethe image percent panel.

 

 

c. Assign the proper settings as shown.

 

 

d. Click OK to add the panel.

 

 

 

Settings

 

 

 

 

 

 

 

 

 

Property

Value

 

 

 

(Name)

sbpnlFileIndex

 

 

 

AutoSize

Contents

 

 

 

ToolTipText

Image Index

 

 

 

 

 

 

 

3

In the OnPaint method, set the text for

sbpnlFileIndex.Text = String.Format

 

this panel to contain the image index

("{0:#}/{1:#}",

 

and album size.

 

 

_album.CurrentPosition+1,

 

 

 

_album.Count);

 

 

 

 

 

 

 

 

 

 

 

The preceding tables have made a number of changes to the OnPaint method. The following code pulls together all of the pieces presented in the preceding tables. We will not discuss these changes in additional detail.

protected override void OnPaint(PaintEventArgs e)

{

if (_album.Count > 0)

{

// Paint the current image

Photograph photo = _album.CurrentPhoto; pbxPhoto.Image = photo.Image;

// Update the status bar. sbpnlFileName.Text = photo.FileName;

sbpnlFileIndex.Text = String.Format("{0}/{1}", _album.CurrentPosition+1, _album.Count);

sbpnlImageSize.Text = String.Format("{0} x {1}", photo.Image.Width, photo.Image.Height);

172

CHAPTER 6 COMMON FILE DIALOGS

Соседние файлы в папке c#