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

The System.Drawing namespace expands the drawing capabilities found in previous Microsoft environments. Chapter 4 presented some information on this namespace and provided an overview of the Graphics class, one of the cornerstones of the .NET drawing interfaces.

In order to draw the current image from our album, we need to modify the OnPaint method to handle the manual drawing of the image. We will implement the Stretch to Fit menu option first as it is the most straightforward. As you’ll recall, this option stretches and perhaps distorts the image to fit the entire display area of the application. This can be done with the following steps. A discussion of the resulting OnPaint method follows this table.

Figure 7.2 When an image is drawn directly on the form, the border and other properties provided by the PictureBox control are no longer available.

IMPLEMENT THE STRETCH TO FIT MENU OPTION

 

Action

Result

 

 

 

1

Find the OnPaint method

protected override void

 

in the MainForm.cs file.

OnPaint(PaintEventArgs e)

 

 

{

 

 

if (_album.Count > 0)

 

 

{

 

 

 

2

When painting the current

// Paint the current image

 

image, obtain the Graphics

Photograph photo = _album.CurrentPhoto;

 

object from the

Graphics g = e.Graphics;

 

 

 

PaintEventArgs parameter.

 

 

 

 

3

To draw the current photo,

switch (_selectedMode)

 

use a switch statement to

{

 

determine the current

default:

 

case DisplayMode.StretchToFit:

 

drawing mode.

 

// Fill entire window with the image

 

How-to

g.DrawImage(photo.Image,

 

this.DisplayRectangle);

 

For the StretchToFit

 

break;

 

option, use the

case DisplayMode.ActualSize:

 

Graphics.DrawImage

 

break;

 

method to fill the entire

 

}

 

window with the image.

 

. . .

 

 

}

 

 

 

4

When the current album is

else

 

empty, draw the default

{

 

color in the window.

// Indicate the album is empty

 

e.Graphics.Clear(SystemColors.Control);

 

 

 

 

. . .

 

 

}

 

 

 

IMAGE DRAWING

203

Draw image in client window c

These changes modify OnPaint to draw the image in the window for the StretchToFit display option, or to clear the window when an empty album is displayed. The resulting OnPaint method is shown here, with the changes just made shown in bold.

protected override void OnPaint(PaintEventArgs e)

{

if (_album.Count > 0)

{

// Paint the current image

Photograph photo = _album.CurrentPhoto;

bOverride the OnPaint method

Graphics g = e.Graphics;

switch (_selectedMode)

{

case DisplayMode.StretchToFit:

// Fill the entire window with the image g.DrawImage(photo.Image, this.DisplayRectangle); break;

case DisplayMode.ActualSize: break;

}

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

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

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

statusBar1.ShowPanels = true;

}

 

 

else

 

 

{

 

 

// Indicate the album

is empty

d Clear the window

e.Graphics.Clear(SystemColors.Control);

statusBar1.Text = "No

Photos in Album";

 

statusBar1.ShowPanels

= false;

 

}

 

 

statusBar1.Invalidate();

base.OnPaint(e);

}

Your application should now compile and run. Load an image, and it should look similar to figure 7.2 shown at the start of this section. The following points are worth noting in our implementation of the OnPaint method.

bThe OnPaint method takes a single PaintEventArgs parameter. We did not discuss this parameter in chapter 6, but a brief mention is warranted here, and an overview is provided in .NET Table 7.3. This class is similar in purpose to the DrawItemEventArgs class presented in chapter 4. The two classes are similar, except that the Paint event and PaintEventArgs class are used for controls, while

204

CHAPTER 7 DRAWING AND SCROLLING

the DrawItem event and DrawItemEventArgs class are used for drawing components or other objects within a control.

cThe Graphics.DrawImage method is used to draw the current photograph in the window. The image is drawn into the area represented by the Form.DisplayRectangle property rather than the ClipRectangle area provided by the PaintEventArgs parameter. This is because ClipRectangle only represents the area

that requires updating, which may not be the entire window. In our case, we need to redraw the entire image to account for changes in the display mode or the size of the drawable area.

dWhen an empty album is present, we draw over any image data that may still be present in the window. The Graphics.Clear method performs this task by painting a single color onto the form. The SystemColors class provides access to the user-definable desktop colors, with the Control property representing the default background color for 3-D controls.

Our application has now taken a step backward. The Stretch to Fit option by definition distorts the image displayed, so the behavior we have here is the same as we saw before. In addition, we have lost our nice border around the image, and resizing the form no longer works.

The border is simply cosmetic and will be addressed in due course toward the end of this chapter. This distortion problem we will address immediately. The resize issue can wait until after the next section.

.NET Table 7.3 PaintEventArgs class

The PaintEventArgs class defines the event data required by the Paint event. This class inherits from the System.EventArgs class, and is part of the System.Windows.Forms namespace.

ClipRectangle

Public Properties

Graphics

Gets the Rectangle representing the area of the object that needs to be painted. This property is read-only.

Gets the Graphics to use when painting the object.

7.2.4IMPLEMENTING A SCALE TO FIT OPTION

The Stretch to Fit option we have used so far is really a poor choice for displaying an image. Users really do not want their images distorted when displayed on the screen. This option makes a nice example to use in our book, but otherwise is not all that useful. Even so, we will keep the option available as a contrast to the more appropriate solution we are about to implement.

Ideally, an image is scaled so that it fits inside the available window space. We will call this option Scale to Fit, and make it the default for our application. An important aspect of this option is the calculation to determine the proper rectangle in which to

IMAGE DRAWING

205

draw the image. This rectangle should be centered in the available area with the same aspect ratio of the original image. Figure 7.3 illustrates the scaling of an image from its original size to fit within the display area of the application. Note that the image is not distorted since the aspect ratio of the image is preserved from its original size.

If you look closely here, you will realize that the image is centered between the base of the menu and the bottom of the window, as opposed to the top of the status bar. This is because the client area includes the status bar, even though our image does not cover it up. This is a minor problem that many users will not notice. Of course, since we have noticed, it will have to be fixed. First we need to create the code necessary to match the figure, and later we will worry about making it better.

Figure 7.3 Scaling an image from its original size to fit the display area is similar to zooming in or out of a graphic. The image looks the same; it just gets smaller or larger.

The operation of scaling a photograph to fit an available area could be a common operation in a photo album application. Because of this, let’s create a method for this algorithm in our MyPhotoAlbum library so that it can be used by other applications, and perhaps later in the book. We will add this method to the Photograph class with the following signature:

public Rectangle ScaleToFit(Rectangle targetArea)

The following steps detail the implementation of this method. Once the method is available, we will look at adding our new option to the menu, and updating our handlers using this new method.

206

CHAPTER 7 DRAWING AND SCROLLING

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