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

Figure 14.6

In this detailed view of Photographs, note how three dots automatically appear when the text length exceeds the width of the column.

14.5.1HANDLING ITEM ACTIVATION

The ultimate goal here is to display either the list of albums or the list of photos in an album within our ListView control. To do this, we must keep track of whether albums or photographs are currently shown in the view, and whether the PhotoAlbum object corresponds to the view when photographs are displayed. The following

steps create private fields in our Form to track this information, and also implement an event handler for the ItemActivate event. Once these are available, we will look at the additional steps required to fully support activation.

Set the version number of the MyAlbumExplorer application to 14.5.

HANDLE THE ITEMACTIVATE EVENT FOR THE LIST VIEW

 

Action

Result

 

 

 

1

Add private fields to track the

private bool _albumsShown = true;

 

current ListView control contents

private PhotoAlbum _album = null;

 

in the MainForm.cs code window.

 

 

 

 

2

Add an ItemActivate event

private void listViewMain_ItemActivate

 

handler to the ListView control.

(object sender, System.EventArgs e)

 

 

{

 

 

 

3

If albums are currently shown and

if (_albumsShown &&

 

an item is selected, then open the

listViewMain.SelectedItems.Count > 0)

 

album corresponding to the

{

 

ListViewItem item

 

selected item.

 

= listViewMain.SelectedItems[0];

 

 

string fileName = item.Tag as string;

 

 

// Open the album for this item

 

 

PhotoAlbum album = null;

 

 

if (fileName != null)

 

 

album = OpenAlbum(fileName);

 

 

if (album == null)

 

 

{

 

 

MessageBox.Show("The photographs for "

 

 

+ "this album cannot be displayed.");

 

 

return;

 

 

}

 

 

 

4

If the album loads successfully,

// Switch to a photograph view

 

load the album’s photographs into

LoadPhotoData(album);

 

the list view.

}

 

}

 

 

 

 

 

ITEM ACTIVATION

473

Of course, we need to implement the LoadPhotoData method that appears in this code. This method should set up the view to display photographs, including an appropriate set of columns, and reset the list of items to hold the set of photographs. Once this is done, there is also the support we created for our albums that must now be implemented for photographs. To help us keep our facts straight, let’s make a list of the tasks we need to perform here.

Define new columns for displaying photographs.

Populate the ListView control with the photographs in the album.

Support column sorting.

Display the photo properties dialog.

Support item editing on photographs.

Allow the user to select the desired view, albums or photos.

We will cover each of these topics in a separate section, in the same order as shown here.

14.5.2DEFINING NEW COLUMNS

As you’ll recall, we defined the list of columns for our control using the ColumnHeader Collection Editor dialog in Visual Studio .NET. Now that we need to display different columns depending on what is displayed, this method no longer makes sense. Instead, we will create the columns programmatically in the LoadAlbumData method. Our new LoadPhotoData method we have yet to implement will define the columns for displaying photographs.

The easiest way to add columns to a ListView control programmatically is through the Columns property. The following steps remove the columns we created in Visual Studio and will add them via the LoadAlbumData method.

CREATE THE ALBUM COLUMNS PROGRAMMATICALLY

 

Action

Result

 

 

 

1

In the MainForm.cs [Design]

Note: This is not strictly required since we clear the

 

window, remove the four

contents of the list, including the column defini-

 

columns currently defined for

tions, as part of the next step. Reducing unneces-

 

the Columns property.

sary clutter in your code is always a good idea, so

 

How-to

performing this step makes sense.

 

 

 

Use the ColumnHeader

 

 

Collection Editor dialog.

 

 

 

 

2

Modify the LoadAlbumData

private void LoadAlbumData(string dir)

 

method to initially clear the

{

 

existing contents of the control.

listViewMain.Clear();

 

 

 

 

 

3

Reset the fields that track the

_albumsShown = true;

 

current album.

if (_album != null)

 

 

{

 

 

_album.Dispose();

 

 

_album = null;

 

 

}

 

 

 

474

CHAPTER 14 LIST VIEWS

CREATE THE ALBUM COLUMNS PROGRAMMATICALLY (continued)

 

Action

Result

 

 

 

4

Define the columns for the

// Define the columns

 

control before the album items

listViewMain.Columns.Add("Name",

 

are loaded.

80, HorizontalAlignment.Left);

 

listViewMain.Columns.Add("Title",

 

 

 

How-to

100, HorizontalAlignment.Left);

 

Use the Add method available

listViewMain.Columns.Add("Pwd",

 

40, HorizontalAlignment.Center);

 

through the Columns property

 

listViewMain.Columns.Add("Size",

 

for the control.

40, HorizontalAlignment.Right);

 

 

// Load the albums into the control

 

 

. . .

 

 

}

 

 

 

The Columns property refers to a ColumnHeaderCollection object. This collection class includes an Add method that creates a new column for the control. One version of this method simply accepts a ColumnHeader class instance. Our code uses a slightly more convenient form, with the following signature:

void Add(string columnText, int width, HorizontalAlignment align);

We can use this same method to add columns when photographs are displayed. The following table summarizes the columns we will use for this purpose.

Columns for displaying photographs

Column

Text

Description

 

 

 

0

Caption

The caption for this photo.

1

Taken

The date the photograph was taken.

2

Photographer

The photographer for this photo.

3

File Name

The fully qualified image file name.

 

 

 

The following table defines constants for our new albums as well as the beginnings of our LoadPhotoData implementation. This table continues our previous steps.

CREATE THE PHOTO COLUMNS PROGRAMMATICALLY

 

Action

Result

 

 

 

5

In the MainForm.cs code

private const int PhotoCaptionColumn = 0;

 

window, create constants to

private const int PhotoDateTakenColumn = 1;

 

hold the positions of the

private const int PhotoPhotographerColumn = 2;

 

private const int PhotoFileNameColumn = 3;

 

columns when photographs are

 

 

 

displayed.

 

 

 

 

6

Add a private LoadPhotoData

private void LoadPhotoData(PhotoAlbum album)

 

method.

{

 

 

 

ITEM ACTIVATION

475

Pho-

CREATE THE PHOTO COLUMNS PROGRAMMATICALLY (continued)

 

Action

Result

 

 

 

7

To implement this method, clear

listViewMain.Clear();

 

the list and set the album fields.

if (_album != null && album != _album)

 

 

_album.Dispose();

 

 

_albumsShown = false;

 

 

_album = album;

 

 

Note: Disposing and assigning the _album field as

 

 

shown is not strictly required here. This will come in

 

 

useful in chapter 15 when we call this method with

 

 

an album other than the default _album used in this

 

 

chapter.

 

 

 

8

Define the columns required for

// Define the columns

 

displaying photographs.

listViewMain.Columns.Add("Caption",

 

 

100, HorizontalAlignment.Left);

 

 

listViewMain.Columns.Add("Taken",

 

 

70, HorizontalAlignment.Center);

 

 

listViewMain.Columns.Add("Photographer",

 

 

100, HorizontalAlignment.Left);

 

 

listViewMain.Columns.Add("File Name",

 

 

200, HorizontalAlignment.Left);

 

 

}

 

 

 

This code defines the four columns required to display photographs. We are now ready to populate the list view with the photos from a selected album.

14.5.3POPULATING THE LISTVIEW

This section completes the implementation of the LoadPhotoData method by creating the ListViewItem objects for the control. The following steps add an item to our control for each Photograph in the album, and define the subitems associated with each item.

In the course of implementing support for photographs, we will need the tograph object itself. We had a similar requirement for PhotoAlbum objects, and were able to use the file name setting to load the album into memory. While the file name is available for our photos as well, our PhotoAlbum class does not provide a good mechanism for locating a Photograph in an album based on the file name.

The most convenient means for locating a specific photograph is based on the index. What we need, then, is a way to look up the index. This value will be stored in the Tag property for our list view item, in a manner similar to how we used this property for photo albums.

Of course, an alternate technique here would be to derive a new class from the ListView class as we discussed at the end of section 14.4. The Tag property is fine for our purposes. In your application, you can use whichever technique seems appropriate for your current and expected requirements.

476

CHAPTER 14 LIST VIEWS

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