ListView Control

The ListView control is similar to a ListBox in that both display lists from which the user can select one or more items (an example of a ListView can be found in Fig. 14.31). The important difference between the two classes is that a ListView can display icons next to the list items (controlled by its ImageList property). Property MultiSelect (a Boolean) determines whether multiple items can be selected. CheckBoxes can be included by setting property CheckBoxes (a Boolean) to true, making the ListView's appearance similar to that of a CheckedListBox. The View property specifies the layout of the ListBox. Property Activation determines the method by which the user selects a list item. The details of these properties and the ItemActivate event are explained in Fig. 14.29.

Figure 14.29. ListView properties and an event.

ListView properties and an event

Description

Common Properties

Activation

Determines how the user activates an item. This property takes a value in the ItemActivation enumeration. Possible values are OneClick (single-click activation), TwoClick (double-click activation, item changes color when selected) and Standard (double-click activation, item does not change color).

CheckBoxes

Indicates whether items appear with CheckBoxes. true displays CheckBoxes. The default is false.

LargeImageList

Specifies the ImageList containing large icons for display.

Items

Returns the collection of ListViewItems in the control.

MultiSelect

Determines whether multiple selection is allowed. The default is TRue, which enables multiple selection.

SelectedItems

Gets the collection of selected items.

SmallImageList

Specifies the ImageList containing small icons for display.

View

Determines appearance of ListViewItems. Possible values are LargeIcon (large icon displayed, items can be in multiple columns), SmallIcon (small icon displayed, items can be in multiple columns), List (small icons displayed, items appear in a single column), Details (like List, but multiple columns of information can be displayed per item) and Tile (large icons displayed, information provided to right of icon, valid only in Windows XP or later).

Common Event

ItemActivate

Generated when an item in the ListView is activated. Does not contain the specifics of which item is activated.

ListView allows you to define the images used as icons for ListView items. To display images, an ImageList component is required. Create one by dragging it to a Form from the ToolBox. Then, select the Images property in the Properties window to display the Image Collection Editor (Fig. 14.30). Here you can browse for images that you wish to add to the ImageList, which contains an array of Images. Once the images have been defined, set property SmallImageList of the ListView to the new ImageList object. Property SmallImageList specifies the image list for the small icons. Property LargeImageList sets the ImageList for large icons. The items in a ListView are each of type ListViewItem. Icons for the ListView items are selected by setting the item's ImageIndex property to the appropriate index.

Figure 14.30. Image Collection Editor window for an ImageList component.

(This item is displayed on page 685 in the print version)

Class ListViewTestForm (Fig. 14.31) displays files and folders in a ListView, along with small icons representing each file or folder. If a file or folder is inaccessible because of permission settings, a MessageBox appears. The program scans the contents of the directory as it browses, rather than indexing the entire drive at once.

Figure 14.31. ListView displaying files and folders.

1 // Fig. 14.31: ListViewTestForm.cs 2 // Displaying directories and their contents in ListView. 3 using System; 4 using System.Drawing; 5 using System.Windows.Forms; 6 using System.IO; 7 8 // Form contains a ListView which displays 9 // folders and files in a directory 10 public partial class ListViewTestForm : Form 11 { 12 // store current directory 13 string currentDirectory = Directory.GetCurrentDirectory(); 14 15 // default constructor 16 public ListViewTestForm() 17 { 18 InitializeComponent(); 19 } // end constructor 20 21 // browse directory user clicked or go up one level 22 private void browserListView_Click( object sender, EventArgs e ) 23 { 24 // ensure an item is selected 25 if ( browserListView.SelectedItems.Count != 0 ) 26 { 27 // if first item selected, go up one level 28 if ( browserListView.Items[ 0 ].Selected ) 29 { 30 // create DirectoryInfo object for directory 31 DirectoryInfo directoryObject = 32 new DirectoryInfo( currentDirectory ); 33 34 // if directory has parent, load it 35 if ( directoryObject.Parent != null ) 36 LoadFilesInDirectory( directoryObject.Parent.FullName ); 37 } // end if 38 39 // selected directory or file 40 else 41 { 42 // directory or file chosen 43 string chosen = browserListView.SelectedItems[ 0 ].Text; 44 45 // if item selected is directory, load selected directory 46 if ( Directory.Exists( currentDirectory + @"" + chosen ) ) 47 { 48 // if currently in C:, do not need ''; otherwise we do 49 if ( currentDirectory == @"C:" ) 50 LoadFilesInDirectory( currentDirectory + chosen ); 51 else 52 LoadFilesInDirectory( 53 currentDirectory + @"" + chosen ); 54 } // end if 55 } // end else 56 57 // update displayLabel 58 displayLabel.Text = currentDirectory; 59 } // end if 60 } // end method browserListView_Click 61 62 // display files/subdirectories of current directory 63 public void LoadFilesInDirectory( string currentDirectoryValue ) 64 { 65 // load directory information and display 66 try 67 { 68 // clear ListView and set first item 69 browserListView.Items.Clear(); 70 browserListView.Items.Add( "Go Up One Level" ); 71 72 // update current directory 73 currentDirectory = currentDirectoryValue; 74 DirectoryInfo newCurrentDirectory = 75 new DirectoryInfo( currentDirectory ); 76 77 // put files and directories into arrays 78 DirectoryInfo[] directoryArray = 79 newCurrentDirectory.GetDirectories(); 80 FileInfo[] fileArray = newCurrentDirectory.GetFiles(); 81 82 // add directory names to ListView 83 foreach ( DirectoryInfo dir in directoryArray ) 84 { 85 // add directory to ListView 86 ListViewItem newDirectoryItem = 87 browserListView.Items.Add( dir.Name ); 88 89 newDirectoryItem.ImageIndex = 0; // set directory image 90 } // end foreach 91 92 // add file names to ListView 93 foreach ( FileInfo file in fileArray ) 94 { 95 // add file to ListView 96 ListViewItem newFileItem = 97 browserListView.Items.Add( file.Name ); 98 99 newFileItem.ImageIndex = 1; // set file image 100 } // end foreach 101 } // end try 102 103 // access denied 104 catch ( UnauthorizedAccessException ) 105 { 106 MessageBox.Show( "Warning: Some fields may not be " + 107 "visible due to permission settings", 108 "Attention", 0, MessageBoxIcon.Warning ); 109 } // end catch 110 } // end method LoadFilesInDirectory 111 112 // handle load event when Form displayed for first time 113 private void ListViewTestForm_Load( object sender, EventArgs e ) 114 { 115 // set Image list 116 Image folderImage = Image.FromFile( 117 currentDirectory + @"imagesfolder.bmp" ); 118 119 Image fileImage = Image.FromFile( 120 currentDirectory + @"imagesfile.bmp" ); 121 122 fileFolder.Images.Add( folderImage ); 123 fileFolder.Images.Add( fileImage ); 124 125 // load current directory into browserListView 126 LoadFilesInDirectory( currentDirectory ); 127 displayLabel.Text = currentDirectory; 128 } // end method ListViewTestForm_Load 129 } // end class ListViewTestForm

(a)

(b)

(c)

To display icons beside list items, create an ImageList for the ListView browser-ListView. First, drag and drop an ImageList on the Form and open the Image Collection Editor. Select our two simple bitmap images, provided in the binRelease folder of this exampleone for a folder (array index 0) and the other for a file (array index 1). Then set the object browserListView property SmallImageList to the new ImageList in the Properties window.

Method LoadFilesInDirectory (lines 63110) populates browserListView with the directory passed to it (currentDirectoryValue). It clears browserListView and adds the element "Go Up One Level". When the user clicks this element, the program attempts to move up one level (we see how shortly). The method then creates a DirectoryInfo object initialized with the string currentDirectory (lines 7475). If permission is not given to browse the directory, an exception is thrown (and caught in line 104). Method LoadFilesInDirectory works differently from method PopulateTreeView in the previous program (Fig. 14.28). Instead of loading all the folders on the hard drive, method LoadFilesInDirectory loads only the folders in the current directory.

Class DirectoryInfo (namespace System.IO) enables us to browse or manipulate the directory structure easily. Method GetDirectories (line 79) returns an array of DirectoryInfo objects containing the subdirectories of the current directory. Similarly, method GetFiles (line 80) returns an array of class FileInfo objects containing the files in the current directory. Property Name (of both class DirectoryInfo and class FileInfo) contains only the directory or file name, such as temp instead of C:myfolder emp. To access the full name, use property FullName.

Lines 8390 and lines 93100 iterate through the subdirectories and files of the current directory and add them to browserListView. Lines 89 and 99 set the ImageIndex properties of the newly created items. If an item is a directory, we set its icon to a directory icon (index 0); if an item is a file, we set its icon to a file icon (index 1).

Method browserListView_Click (lines 2260) responds when the user clicks control browserListView. Line 25 checks whether anything is selected. If a selection has been made, line 28 determines whether the user chose the first item in browserListView. The first item in browserListView is always Go up one level; if it is selected, the program attempts to go up a level. Lines 3132 create a DirectoryInfo object for the current directory. Line 35 tests property Parent to ensure that the user is not at the root of the directory tree. Property Parent indicates the parent directory as a DirectoryInfo object; if no parent directory exists, Parent returns the value null. If a parent does directory exist, then line 36 passes the full name of the parent directory to method LoadFilesInDirectory.

If the user did not select the first item in browserListView, lines 4055 allow the user to continue navigating through the directory structure. Line 43 creates string chosen, which receives the text of the selected item (the first item in collection SelectedItems). Line 46 determines whether the user has selected a valid directory (rather than a file). The program combines variables currentDirectory and chosen (the new directory), separated by a backslash (), and passes this value to class Directory's method Exists. Method Exists returns TRue if its string parameter is a directory. If this occurs, the program passes the string to method LoadFilesInDirectory. Because the C: directory already includes a backslash, a backslash is not needed when combining currentDirectory and chosen (line 50). However, other directories must include the slash (lines 5253). Finally, displayLabel is updated with the new directory (line 58).

This program loads quickly, because it indexes only the files in the current directory. This means that a small delay may occur when a new directory is loaded. In addition, changes in the directory structure can be shown by reloading a directory. The previous program (Fig. 14.28) may have a large initial delay as it loads an entire directory structure. This type of trade-off is typical in the software world.

Software Engineering Observation 14 2

When designing applications that run for long periods of time, you might choose a large initial delay to improve performance throughout the rest of the program. However, in applications that run for only short periods of time, developers often prefer fast initial loading times and small delays after each action.

TabControl Control

Категории