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

Set the version number of the MyPhotos application to 7.2.

 

 

DELETE THE PICTUREBOX CONTROL

 

 

 

 

 

Action

 

Result

 

 

 

 

1

Display the MainForm.cs

 

 

 

[Design] window.

 

 

 

 

 

 

2

Delete the PictureBox

 

The control no longer appears on the form.

 

control.

 

In the MainForm.cs file, the definition for the control (the

 

 

 

 

How-to

 

pbxPhoto variable) and all references to it in the

 

Select the Delete item

 

InitializeComponent method are removed.

 

from the control’s context

Note: nonautomated references to this variable must be

 

menu, or simply click on

 

 

 

removed by hand. This will be done during the course of

 

the control and press the

 

 

 

this section.

 

Delete key.

 

 

 

 

 

 

 

 

With this task completed, our way is clear to implement the functionality previously provided by the PictureBox control in our MainForm control directly.

7.2.2HANDLING THE IMAGE MENU

One of the unfortunate but necessary side effects of nuking the PictureBox control is that our processing of the Image menu no longer makes sense. We built this with the PictureBoxSizeMode enumeration values in mind. Since we are no longer using this control, we need to change how our menu works.

As an alternative solution, we will create our own enumerator for this purpose to use in place of the PictureBoxSizeMode enumeration. We could provide a long discussion of the individual changes required here, but this is chapter 7 so we’ll just plunge ahead.

In this section we’ll create the new enumeration and begin the process of modifying our menu handlers. The subsequent sections will address issues specific to the child menu items of the Image menu, and complete our implementation of the menu handlers.

 

REPLACE THE MODEMENUARRAY MEMBER

 

 

 

 

Action

Result

 

 

 

1

In the MainForm.cs file,

 

 

delete the modeMenuArray

 

 

and _selectedImageMode

 

 

fields.

 

 

 

 

IMAGE DRAWING

199

REPLACE THE MODEMENUARRAY MEMBER (continued)

 

Action

Result

 

 

 

2

Create a private

/// <summary>

 

DisplayMode enumerator

/// Mode settings for the View->Image

 

in the MainForm class.

/// submenu. The order and values here

 

/// must correspond to the index of

 

 

 

 

/// menus in the Image submenu.

 

 

/// </summary>

 

 

private enum DisplayMode

 

 

{

 

 

StretchToFit = 0,

 

 

ActualSize = 1

 

 

}

 

 

 

3

Create a private instance of

private DisplayMode _selectedMode

 

this enumerator called

= DisplayMode.StretchToFit;

 

_selectedMode.

 

 

 

 

4

Replace the use of the old

private void statusBar1_DrawItem

 

_selectedImageMode

(object sender, System.Windows.Forms.

 

StatusBarDrawItemEventArgs sbdevent)

 

with the appropriate use of

 

{

 

_selectedMode in the

 

if (sbdevent.Panel == sbpnlImagePercent)

 

statusBar1_DrawItem

{

 

method.

// Calculate percent of image shown

 

 

int percent = 100;

 

 

if (_selectedMode == DisplayMode.ActualSize)

 

 

{

 

 

Photograph photo

 

 

= _album.CurrentPhoto;

 

 

Rectangle dr = this.ClientRectangle;

 

 

int imgWidth = photo.Image.Width;

 

 

int imgHeight = photo.Image.Height;

 

 

percent = 100

 

 

* Math.Min(dr.Width, imgWidth)

 

 

* Math.Min(dr.Height, imgHeight)

 

 

/ (imgWidth * imgHeight);

 

 

}

 

 

. . .

 

 

}

 

 

}

 

 

 

5

Replace all other instances

The instances of this variable in menuImage_Popup,

 

of the old

menuImage_ChildClick, and OnPaint are replaced.

 

_selectedImageMode

Note: Some tweaking of this code is required to make it

 

with the new

 

work properly. The changes are shown in the subsequent

 

_selectedMode.

 

text and will evolve throughout this section.

 

 

 

 

 

Let’s look at the menu handlers here to see how our new DisplayMode enumeration is used. The Popup event handler is called whenever the Image submenu is about to display, while the Click handler is called whenever an Image submenu is selected.

protected void menuImage_Popup (object sender, System.EventArgs e)

{

if (sender is MenuItem)

{

bool bImageLoaded = ( _album.Count > 0 );

MenuItem miParent = (MenuItem)sender;

200

CHAPTER 7 DRAWING AND SCROLLING

Invalidate d current
window

foreach (MenuItem mi in miParent.MenuItems)

{

mi.Enabled = bImageLoaded;

mi.Checked = (this._selectedMode == (DisplayMode)mi.Index);

}

}

Cast integer to b enumerated type

}

protected void menuImage_ChildClick (object sender, System.EventArgs e)

{

if (sender is MenuItem)

{

MenuItem mi =

(MenuItem)sender;

Cast integer to

 

 

 

_selectedMode

= (DisplayMode) mi.Index;

b enumerated type

switch (_selectedMode)

c

 

{

 

Handle enumeration

default:

case DisplayMode.StretchToFit:

// Stretch image to fit the display area. this.Invalidate();

break;

case DisplayMode.ActualSize:

// Display image at actual size. this.Invalidate();

break;

}

statusBar1.Invalidate();

}

This code raises some interesting points about the use of enumerated types.

bThis line simply casts an integer value to an enumerated type. With the extensive error and type checking built into C#, you might think it would be an error to cast an integer to an enumeration value that does not exist. In fact, a standard C# enumeration by definition can hold any integer value, so any integer value can be cast to any enumeration type.

cThis line uses a switch statement to perform the appropriate action based on the current display mode setting. Notice how the StretchToFit case is used as the default setting.

dSince our image will now be drawn directly on the form, we need to call the Form.Invalidate method to force the application to redraw the window using the new setting.

Of course, the menuImage_ChildClick method is not finished yet. We will fill this method in as we enable the corresponding display modes.

IMAGE DRAWING

201

Before we do, one other feature is missing. Our wonderful context menu disappeared along with the PictureBox control. The menu is still around, of course, and is still initialized by the DefineContextMenu method to contain a copy of the View menu. The menu is just not hooked up to any controls at the moment, so it never appears.

We can fix this by attaching this menu to our Form class. Continuing our previous steps:

 

ASSOCIATE THE CONTEXT MENU WITH THE FORM

 

 

 

 

Action

Result

 

 

 

7

Display the properties for

 

 

the MainForm object in the

 

 

MainForm.cs [Design]

 

 

window.

 

 

 

 

8

Set the ContextMenu

The property is set in the InitializeComponent method of

 

property to the

the MainForm.cs source file.

 

ctxtMenuView menu.

this.ContextMenu = ctxtMenuView;

 

 

 

How-to

 

 

Click the down arrow next

 

 

to the ContextMenu

 

 

property to display the

 

 

available menus.

 

 

 

 

Our context menu is now associated with the top-level form, and will appear whenever the user right-clicks anywhere in the window.

Your program may or may not compile here, depending on what you did to the OnPaint method when the _selectedImageMode field was removed. We’ll cover this as part of the next section.

7.2.3IMPLEMENTING THE STRETCH TO FIT OPTION

The modification of our Image menu handlers fully eradicates the PictureBox control from our application. While the PictureBox control created some problems, it also drew the current photograph for us. Now we will need to do this by hand, the result of which is shown in figure 7.2. You will note in this figure that the application is lacking the border previously shown around the image by the PictureBox control. This will be addressed later in the chapter.

202

CHAPTER 7 DRAWING AND SCROLLING