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

12.3IMAGE BUTTONS

So far the buttons in this book have contained text strings only. In fact, both button and label controls support the display of an image instead of or in addition to text. In this section we will look at images on buttons. Supporting images on labels is quite similar.

For button controls, imaging support is defined by the ButtonBase class, so this discussion applies equally well to the Button, RadioButton, and CheckBox objects. A summary of this class was provided in .NET Table 9.4 on page 292. For our purposes, we will focus on the Image property for assigning an image to a button, and the ImageAlign property to specify how the image is aligned within the button. An index into a list of images can also be specified using the ImageIndex and ImageList properties. We will cover image lists when we discuss toolbars in chapter 13.

As our example, we will add the ability to move to the next or previous photograph in our PhotoEditDlg form. Currently, when a user wants to edit the properties of two different images, he or she must display and edit the dialogs separately from the main form, so this change provides a nice shortcut for this type task. Figure 12.2 shows the dialog with our new changes. As you can see, two small image buttons have been added to the top of the form.

Figure 12.2

Buttons can display text only, an image only, or both an image and text. The Prev and Next buttons in this figure display both types of data.

This change will require more modifications than you might imagine. Our current dialog code does not make any allowances for more than a single photo. To take a somewhat incremental approach to this change, we will first add these buttons with only text displayed, and later replace the text with an image.

12.3.1IMPLEMENTING NEXT AND PREV BUTTONS

We have been placing buttons on forms since chapter 1, so this section will run through the steps required to add and manage our new buttons. A number of steps are required here to convert our dialog from using the positional methods in the PhotoAlbum class to an index-based scheme that can support our new buttons.

IMAGE BUTTONS

393

To begin, let’s add the new buttons to our window. In order to fit additional controls in our PhotoEditDlg form, we need to do some redecorating. As you’ll recall, this form inherits its size from the BaseEditDlg form, so we are not able to resize the form itself. Our first task, then, is to squeeze the existing controls together a bit and insert our new buttons at the top of the form.

Set the version number of the MyPhotoAlbum library to 12.3.

ADD THE NEXT AND PREV BUTTONS

 

 

 

Action

 

 

 

Result

 

 

 

 

 

 

 

 

1

In the PhotoEditDlg.cs [Design] window, adjust

Note: The instructions here simply

 

the existing controls so there is room for the

reflect how I made this change, using

 

new buttons at the top of the form.

the default grid size of 8. Your form

 

How-to

 

 

 

 

may vary a little, so do whatever

 

 

 

 

 

appears to work best.

 

a. Resize the Notes text box to be one grid

 

 

 

size smaller in height.

 

 

 

 

 

 

b. Move the Notes label down as well.

 

 

c. Resize the base of the Panel to be closer

 

 

to the bottom control.

 

 

 

 

 

 

d. Move the Panel down two grid sizes.

 

 

 

 

 

 

 

 

 

2

Add a Next button to the top of the form.

 

 

 

 

Settings

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Property

 

 

Value

 

 

 

 

(Name)

 

btnNext

 

 

 

 

Size

 

 

60, 20

 

 

 

 

 

 

Text

 

 

N&ext

 

 

 

 

 

 

 

 

 

 

 

3

Add a Prev button to the left of the Next

 

 

button.

 

 

 

 

 

 

 

 

Settings

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Property

 

 

Value

 

 

 

 

(Name)

 

 

btnPrev

 

 

 

 

Size

 

 

60,20

 

 

 

 

 

 

Text

 

 

Pre&v

 

 

 

 

 

 

 

 

 

 

 

4

Adjust the tab order for the form’s controls to

Note: The order does not affect our

 

have a reasonable sequence.

discussion, so use whatever sequence

 

 

 

 

 

 

 

 

 

makes the most sense to you.

 

 

 

 

 

 

 

 

 

 

Each of these buttons will require a Click handler, and this is where it gets a bit tricky. You might be tempted to implement these handlers as follows:

private void btnNext_Click(object sender, System.EventArgs e)

{

// Increment the current position (not our approach) _album.CurrentNext();

}

394

CHAPTER 12 A .NET ASSORTMENT

private void btnPrev_Click(object sender, System.EventArgs e)

{

// Decrement the current position (not our approach) _album.CurrentPrev();

}

Unfortunately, life is not so simple. There are two major problems with this approach. The first is that the parent form, in this case the main form of our MyPhotos application, may rely on the existing value of the current album position. This code might adversely affect some activity in the application, or even cause a fatal error.

The second problem is that any changes made to the existing photograph are discarded whenever the user views a new photograph. Clicking the Next button should not throw out the changes already made.

As a result, we need to take a different approach. To resolve the first problem, that of adversely affecting the parent form, we will use a direct index into the album rather than modifying the current album position. We will address the second problem, that of not discarding user changes, in a moment.

ACCESS THE ALBUM USING AN INDEX VALUE

 

Action

Result

 

 

 

5

Create an _index member in the

private int _index;

 

PhotoEditDlg class.

 

 

 

 

6

Initialize this field in the constructor.

public PhotoEditDlg(PhotoAlbum album)

 

Note: This field must be initialized before

{

 

. . .

 

the call to the ResetSettings method.

// Initialize the dialog settings

 

 

_album = album;

 

 

_index = album.CurrentPosition;

 

 

ResetSettings();

 

 

}

 

 

 

7

Update the remainder of the file to access

For example, in the ResetSettings method:

 

the current photograph using this new

protected override void ResetSettings()

 

field rather than the CurrentPhoto

 

{

 

method.

. . .

 

Note: This requires updating the Reset-

Photograph photo = _album[_index];

 

Settings, SaveSettings, and

. . .

 

cmbxPhotographer_Validated

 

 

 

methods.

 

 

 

 

8

Also in the ResetSettings method,

btnPrev.Enabled = !(_index == 0);

 

enable or disable the Next and Prev

btnNext.Enabled

 

buttons based on the current index.

= !(_index == _album.Count - 1);

 

}

 

 

 

 

 

These changes will allow us to modify the index value in our event handlers, and the current album position will not be affected. The second problem, that of saving any changes made, requires that we save the existing photograph before moving on to the next or previous one. Of course, we do not want to do this unless the user has actually

IMAGE BUTTONS

395

made some changes. As a result, we will track the original values for the photograph, and later compare these against the new values when moving to a new photograph.

The following steps continue our changes and build the infrastructure needed to do this. Following this table, we will make use of this infrastructure to save any changes made by the user.

TRACK WHEN PHOTOGRAPH SETTINGS ARE MODIFIED

 

Action

Result

 

 

 

9

Create variables to hold the original

private string _origCaption;

 

caption, date taken, and

private DateTime _origDateTaken;

 

photographer values.

private string _origPhotographer;

 

 

 

Note: The file name cannot be

 

 

changed, and the Notes value will

 

 

require a different approach.

 

 

 

 

10

Create a SetOriginals method to

protected void SetOriginals()

 

initialize these variables.

{

 

 

Photograph photo = _album[_index];

 

 

if (photo != null)

 

 

{

 

 

_origCaption = photo.Caption;

 

 

_origDateTaken = photo.DateTaken;

 

 

_origPhotographer = photo.Photographer;

 

 

}

 

 

}

 

 

 

11

Ensure these values are initialized

public PhotoEditDlg(PhotoAlbum album)

 

in the constructor.

{

 

 

. . .

 

 

// Initialize the dialog settings

 

 

_album = album;

 

 

_index = album.CurrentPosition;

 

 

ResetSettings();

 

 

SetOriginals();

 

 

}

 

 

 

You may have noticed that the Notes text box value is suspiciously missing here. While comparing a string object to the Text property works fine for a single-line TextBox control, it is not the preferred method for multiline text boxes. Instead, the Lines property should be compared line by line with the original settings. This is a little more work than we want to do, so we will simply mark this text box modified whenever the user modifies the text.

Recording whether the Notes text has changed will allow us to conditionally save a photograph’s new settings, which we will do as part of the following steps:

396

CHAPTER 12 A .NET ASSORTMENT

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