Home

.NET Controls: The List View

 

The List View Control

 

Introduction

A list box is used to display a list of strings and all items of that control are primarily strings. To go a little further than a simple list of strings, the Microsoft Windows operating system provides the list view control. A list view is used to display a list of items to the user but it can be configured to change the type of display.

 

List View Creation

The list view control is made available in the .NET Framework through the ListView class that is represented in the Windows Forms section of the Toolbox by the TreeView button. To add a list view to your application, you can click ListView in the Toolbox and click the form or another container.

To programmatically create a list view, you can declare a variable of type ListView, use the new operator to instantiate it and add it to its host's list of controls through a call to the Controls.Add() method. Here is an example:
private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width      = 420;
	lvwCountries.Height     = 160;
	Controls.Add(lvwCountries);
}

After this declaration, an empty rectangular control is created and added to your application. You can then start populating it.

Practical LearningPractical Learning: Introducing the Tree View Control

  1. Start a new Windows Forms Application named DeptStore2
  2. Change the form's Text to Department Store
  3. In the Windows Forms section of the Toolbox, click ListView and click the form
  4. Using the Properties window, change its properties as follows:
    (Name): lvwStoreItems
    Anchor: Top, Bottom, Left, Right
  5. Add a Button to the form and change its properties as follows:
    (Name): btnClose
    Text: Close
    Anchor: Bottom, Right

     
  6. Double-click the Close button and implement its Click event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    {
    	Close();
    }
  7. Save all
 

The Items of a List View

 

Introduction to Creating List View Items

To create the items of a list view, you can use the ListViewItem Collection Editor of Microsoft Visual Studio .NET. To access it, after adding a ListView objectto your application, you can click the ellipsis button of its Items field in the Properties window:

ListViewItem Collection Editor

At design time and in the ListViewItem Collection Editor, to create a new item, you can click the Add button:

The items of a list view are stored in a property called Items. The Items property is based on the ListView.ListViewItemCollection class. To create a new list view item, the ListViewItemCollection class is equipped with the Add() method which is overloaded with three versions. One of the versions of this method uses the following syntax:

public virtual ListViewItem Add(string text);

This method expects a string that will display as the new item. Here is an example:
private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width      = 420;
	lvwCountries.Height     = 160;
	Controls.Add(lvwCountries);

	lvwCountries.Items.Add("Egypt");
}

As the Items property is in fact a list, each item of this collection is represented by the Item property of the ListViewItemCollection class. This Item property is based on the ListViewItem class. The ListViewItem class is equipped with various constructors, the default of which allows you to instantiate an item without giving much details.

Instead of directly passing a string to the ListViewItemCollection.Add() method, you can first create a ListViewItem object and pass it to the following version of the ListViewItemCollection.Add() method:

public virtual ListViewItem Add(ListViewItem value);

This method expects a ListViewItem value. One way you can use it consists of providing the string the item would display. To do this, you can use the following constructor of the ListViewItem class:

public ListViewItem(string text);

This constructor expects as argument the text that the new item will display. Here is an example:
private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width      = 420;
	lvwCountries.Height     = 160;
	Controls.Add(lvwCountries);

	lvwCountries.Items.Add("Egypt");

	ListViewItem lviPortugal = new ListViewItem("Portugal");
	lvwCountries.Items.Add(lviPortugal);
}

You can use any of these techniques to create as many items as necessary. Alternatively, if you have many items to create, you can first store them in an array of ListViewItem values, then call the ListView.ListViewItemCollection.AddRange() method. The syntax of this method is:

public void AddRange(ListViewItem[] items);

This method takes as argument an array of ListViewItem objects. Here is an example:

private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width      = 420;
	lvwCountries.Height     = 160;
	Controls.Add(lvwCountries);

	lvwCountries.Items.Add("Egypt");

	ListViewItem lviPortugal = new ListViewItem("Portugal");
	lvwCountries.Items.Add(lviPortugal);

	ListViewItem[] lviCountries = { new ListViewItem("Australia"),
				  new ListViewItem("Mali"),
				  new ListViewItem("Sweden"),
				  new ListViewItem("Venezuela") };

	lvwCountries.Items.AddRange(lviCountries);
}

Alternatively, you can create an array of strings and pass it to the following constructor of the ListView class:

public ListViewItem(string[] items);
 

Practical Learning Practical Learning: Creating List View Items

  1. To add a new form to the application, on the main menu, click Project -> Add Windows Form...
  2. In the Templates section, make sure that click Windows Forms is selected. Set the name to NewStoreItem and press Enter
  3. Design the form as follows:
     
    Control Name Text Other Properties
    Label   Item #:  
    TextBox txtItemNumber   Modifiers: Public
    Button btnOK OK DialogResult: OK
    Button btnCancel Cancel DialogResult: Cancel
    Form   New Make AcceptButton: btnOK
    CancelButton: btnCancel
    FormBorderStyle: FixedDialog
    MaximizeBox: False
    MinimizeBox: False
    ShowInTaskbar: False
    StartPosition: CenterScreen
  4. Display the first form (Form1.cs [Design]). Add a Button to it and change its properties as follows:
    (Name): btnNewItem
    Text: New Item
    Anchor: Bottom, Left
  5. Double-click the button
  6. To create a new item, implement the event as follows:
     
    private void btnNewItem_Click(object sender, System.EventArgs e)
    {
    	NewStoreItem frmItem = new NewStoreItem();
    
    	Random rndNumber = new Random(DateTime.Now.Millisecond);
    	int number1 = rndNumber.Next(100, 999);
    	int number2 = rndNumber.Next(100, 999);
    	String itemNumber = number1 + "-" + number2;
    
    	frmItem.txtItemNumber.Text = itemNumber;
    	if( frmItem.ShowDialog() == DialogResult.OK )
    	{
    		ListViewItem lviStoreItem = new ListViewItem(frmItem.txtItemNumber.Text);
    		this.lvwStoreItems.Items.Add(lviStoreItem);
    	}
    }
  7. Return to the first form (Form1.cs [Design]). In the Windows Forms section of the Toolbox, click ContextMenu and click the form
  8. On the form, click ContextMenu and click Type Here. Create the following menu items:
     
    Text (Name) Shortcut
    New Item btnNewItem CtrlN
    Edit mnuEditItem CtrlE
    Delete mnuDelItem Del
    Remove all Items mnuDeleteAll ShiftDel
  9. On the form, click the list view. In the Properties window, set its ContextMenu to contextMenu1
  10. Under the form, click contextMenu1
  11. In the form, click Context Menu and click New Item
  12. In the Properties window, click the Events button
  13. In the Click field, select  btnNewItem_Click
  14. Execute the application to test the form
  15. Close the form and return to your programming environment

List View Items and Their Icons

One of the fundamental differences between a list box and a list view is that this one has a built-in capability to display icons but this is only an option. Unlike the tree view, the list view uses two sets of pictures. This means that two icons would be associated to each item. One of the icons should have a 32x32 pixels size and the other should have a 16x16 pixels size. The set of 32x32 pixels list is referred to as large icons. The other set is referred to as small icons. Before using the pictures, you should first store them in image lists. Each set must be stored in its own ImageList object.

To support the various sets of icons, the ListView class is equipped with a property called LargeImageList for the 32x32 icons and another property called SmallImageList for the 16x16 icons. After creating both ImageList objects, you can assign each to the appropriate property.

When creating an item using the ListViewItemCollection.Add() method, if you plan to display an icon next to it, you can use the following version of the method:

public virtual ListViewItem Add(string text,  int imageIndex);

The first argument is the string that will display for the item. The second argument is the index of the icon in the ImageList property. This method returns a reference to the ListViewItem object that was added to the control.

We saw that you can also first create a ListViewItem object to add to the control. If you use this approach and you want the item to display an icon, you can use the following constructor of the TreeViewItem class:

public ListViewItem(string text, int imageIndex);

This constructor uses the same arguments as the version of the ListViewItemCollection.Add() method above. You can also create an array of strings and assign them the same icon. To do this, you can create the item with the following constructor of the TreeViewItem class:

public ListViewItem(string items, int imageIndex);
 

Practical LearningPractical Learning: Associating Icons With Nodes

  1. To create an icon, on the main menu, click File -> New -> File... In the New File dialog box, click Icon File and click New
  2. Design the icon as follows:
     
  3. Right-click a white area in the main window -> Current Image Type -> 16x16, 16 colors
  4. Design the icon as follows:
     
  5. To save the icon, on the main menu, click File -> Save Icon1 As...
  6. Locate the folder that contains the current project and display it in the Save In combo box. Change the Filename to Babies.ico and click Save
  7. Following the same steps, create a New Icon File and design it as follows:
     
  8. As done above, display the 16x16, 16 colors version of the icon and design the icon as follows:
     
  9. Save the icon as Teens.ico
  10. Follow the same steps to add a New Icon File and design it as follows:
     
  11. Display its 16x16, 16 colors version and design it as follows:
     
  12. Save the icon as Women.ico
  13. Add another Icon File and design it as follows:
     
  14. Access its 16x16, 16 colors version and design it as follows:
     
  15. Save the icon as Men.ico 
  16. Add one more Icon File and design it as follows:
     
  17. Display its 16x16, 16 colors version and design it as follows:
     
  18. Save the icon as Misc.ico 
  19. Display the first form.
    In the Toolbox, click ImageList and click the form
  20. In the Properties window, change its name to imgLarge
  21. Change the ImageSize to 32, 32
  22. Click the ellipsis button of the Images field
  23. In Image Collection Editor, click Add
  24. Locate the folder that contains the current project and display it in the Look In combo box
  25. Select Babies.ico and click Open
  26. In the same way, add the other pictures in the following order: Teens.ico, Women.ico, Men.ico, and Misc.ico
  27. Click OK
  28. In the Toolbox, click ImageList and click the form
  29. In the Properties window, change its name to imgSmall
  30. In the Properties window, click the ellipsis button of the Images field
  31. In Image Collection Editor, click Add
  32. Select Babies.ico, Teens.ico, Women.ico, Men.ico, and Misc.ico
  33. Click OK
  34. Access the NewStoreItem form and change its design as follows:
     
    Control Name Text Other Properties
    Label   Category:  
    ComboBox cboCategories Miscellaneous Modifiers: Public
    Items: Babies, Teens, Women, Men, Miscellaneous
  35. Display the first form and click the list view on it
  36. In the Properties window, change the following properties:
    LargeImageList: imgLarge
    SmallImageList: imgSmall
  37. Double-click the New Item button and change its Click event as follows:
     
    private void btnNewItem_Click(object sender, System.EventArgs e)
    {
    	NewStoreItem frmItem = new NewStoreItem();
    	int icoSelected = 4;
    	string strCatSelected = "Miscellaneous";
    
    	Random rndNumber = new Random(DateTime.Now.Millisecond);
    	int number1 = rndNumber.Next(100, 999);
    	int number2 = rndNumber.Next(100, 999);
    	String itemNumber = number1 + "-" + number2;
    
    	frmItem.txtItemNumber.Text = itemNumber;
    	if( frmItem.ShowDialog() == DialogResult.OK )
    	{
    		strCatSelected =  frmItem.cboCategories.Text;
    
    		if( strCatSelected.Equals("Babies") )
    			icoSelected = 0;
    		else if( strCatSelected.Equals("Teens") )
    			icoSelected = 1;
    		else if( strCatSelected.Equals("Women") )
    			icoSelected = 2;
    		else if( strCatSelected.Equals("Men") )
    			icoSelected = 3;
    
    	ListViewItem lviStoreItem = new ListViewItem(frmItem.txtItemNumber.Text, icoSelected);
    		this.lvwStoreItems.Items.Add(lviStoreItem);
    	}
    }
  38. Execute the application to test it
  39. Try creating an item for each category (use the random numbers generated by the application)
     
  40. Close the form and return to your programming environment

View Styles

To set it apart from the list box, a list view provides various options of displaying its items. To support this, the ListView class is equipped with the View property that is based on the View enumerator. Three of its members are:

  • LargeIcon: In this view, the control displays a list of items using icons with a 32x32 pixels size of icons. The string of the item displays under its corresponding icon:
     
    List View: Large Icons
  • List: Each item appears with a small icon to its left. The first item appears to the left side of the view. The next item (usually in alphabetical order) appears under it, and so on. If there are more items to fit in one column, the list continues with a new column to the right of the previous one. This continues until the list is complete:
     
    List View: List
  • SmallIcon: Like the List option, this view uses small icons to display its items. The icon of an item appears to the left of its string. The first item appears in the top-left section of the view. The next item is positioned to the right of the previous item. The list continues to the right. If there are more items, the subsequent ones display on the next line, until the list is complete
      
    List View Style: Small Icons

As seen so far, you can use one of four different displays on a list view. Furthermore, you can give the user the ability to change views as needed. The different displays of the list view are controlled by the View property of the ListView class. To specify the type of view to use, assign the desired member of the View enumerator to the ListView.View property.

Practical LearningPractical Learning: Using View Styles

  1. To create an icon, on the main menu, click File -> New -> File... In the New File dialog box, click Icon File and click New
  2. Right-click the white area and click Delete Image Type
  3. Design the 16x16 pixels version of the icon as follows:
     
  4. Save the icon as LrgIcon.ico in the folder of the current project
  5. In the same way, add another Icon File. Delete its 32x32 version. Design the 16x16 version as follows:
     
  6. Save the icon as SmIcon.ico 
  7. Add another Icon File. Delete its 32x32 version and design the 16x16 version as follows:
     
  8. Save the icon as List.ico 
  9. Add another Icon File. Delete its 32x32 version and design the 16x16 version as follows:
     
  10. Save the icon as Details.ico
  11. Change the design of the first form as follows:
     
    Control Name Appearance Checked Image
    RadioButton btnLargeIcons Button   LrgIcons.ico
    RadioButton btnSmallIcons Button   SmIcons.ico
    RadioButton btnList Button   List.ico
    RadioButton btnDetails Button True Details.ico
  12. Double-click each of the new buttons from left to right and implement their Click events as follows:
     
    private void btnLargeIcons_CheckedChanged(object sender, System.EventArgs e)
    {
    	this.lvwStoreItems.View = View.LargeIcon;
    }
    
    private void btnSmallIcons_CheckedChanged(object sender, System.EventArgs e)
    {
    	this.lvwStoreItems.View = View.SmallIcon;
    }
    
    private void btnList_CheckedChanged(object sender, System.EventArgs e)
    {
    	this.lvwStoreItems.View = View.List;
    }
    
    private void btnDetails_CheckedChanged(object sender, System.EventArgs e)
    {
    	this.lvwStoreItems.View = View.Details;
    }
  13. Return to the first form. Under the form, click contextMenu1
  14. On the form, click Context Menu and click Type Here under the other menu items
  15. Type View and click Type Here on its right
  16. Create the sub-menu items and select the events in the Events section of the Properties window as follows:
     
    Menu Text (Name) Event -> Click
    Large Icons mnuLargeIcons btnLargeIcons_CheckedChanged
    Small Icons mnuSmallIcons btnSmallIcons_CheckedChanged
    List mnuList btnList_CheckedChanged
    Details mnuDetails btnDetails_CheckedChanged
     
  17. Save all

The Columns of a List View

 

Introduction

Another characteristic that sets the list view apart from the list box is that the former can provide more information about each item of its list. Based on this, each type of item we have created so far can be equipped with its own list of sub-items. The view would appear as follows:

List View Style: Details
 

Creating Columns

Before creating the sub-items of a list view, you may need to plan it first to identify the types of information you want to provide. To guide the user with the type of information that each item would display, you can create a column for each type. To support columns, the ListView class is equipped with the Columns property. The Columns property is an object of type ListView.ColumnHeaderCollection. As its name indicates, the Columns property represents a list of columns. Each column is based on the ColumnHeader class.

To create a column, you can call the ColumnHeaderCollection.Add() method that is overloaded with two versions. One of the versions of this method uses the following syntax:

public virtual ColumnHeader Add(string caption, int width, HorizontalAlignment textAlign);

The first argument of this method is referred to as the column's caption. It is text that would display in the column header. The second argument is a natural number that represents the distance from the left to the right borders of the column. The last argument specifies how the caption of the column would be aligned. The options are the same as those of the text box: Left, Center, or Right. The default value is Left.

Here is an example of creating a column by calling this method:

private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width      = 420;
	lvwCountries.Height     = 160;
	lvwCountries.View = View.Details;
	Controls.Add(lvwCountries);

	lvwCountries.Columns.Add("Name", 120, HorizontalAlignment.Left);
}

As mentioned earlier, a column is in fact an object of type ColumnHeader. This class is equipped with all the necessary characteristics of a column header:

  • Caption: The Text property holds the string that displays on top of the column
  • Width: This property represents the width of the column
  • Text Alignment: The TextAlign property specifies the horizontal alignment of its string. This property uses a value of type HorizontalAlignment, which is the same as that of the text box
  • Index: Since the columns are stored in a collection, this property allows you to get the index of this column in the collection it belongs to
  • The Parent List View: If you want to know what list view the current column header belongs to, you can access its ColumnHeader.ListView property

Instead of defining a column in the Add() method, you can first create an object based on the ColumnHeader class and then pass it to the following version of the ColumnHeaderCollection.Add() method:

public virtual int Add(ColumnHeader value);

This method takes as argument a ColumnHeader object. Here is an example:

private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width      = 420;
	lvwCountries.Height     = 160;
	lvwCountries.View = View.Details;
	Controls.Add(lvwCountries);

	lvwCountries.Columns.Add("Name", 120, HorizontalAlignment.Left);
	ColumnHeader colArea = new ColumnHeader();
	colArea.Text = "Area";
	colArea.Width = 80;
	colArea.TextAlign = HorizontalAlignment.Right;
	lvwCountries.Columns.Add(colArea);
}

Instead of adding one column at a time as we have done above, you can first create an array of ColumnHeader objects and pass it to the ListView.ColumnHeaderCollection.AddRange() method. Its syntax is:

public virtual void AddRange(ColumnHeader values[]);

Here is an example of using it:

private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width      = 420;
	lvwCountries.View = View.Details;
	Controls.Add(lvwCountries);

	lvwCountries.Columns.Add("Name", 120, HorizontalAlignment.Left);
	ColumnHeader colArea = new ColumnHeader();
	colArea.Text = "Area";
	colArea.Width = 80;
	colArea.TextAlign = HorizontalAlignment.Right;
	lvwCountries.Columns.Add(colArea);

	ColumnHeader colPopulation = new ColumnHeader();
	colPopulation.Text = "Population";
	colPopulation.Width = 78;
	colPopulation.TextAlign = HorizontalAlignment.Right;

	ColumnHeader colCapital = new ColumnHeader();
	colCapital.Text = "Capital";
	colCapital.Width = 96;
	colCapital.TextAlign = HorizontalAlignment.Left;

	ColumnHeader colCode = new ColumnHeader();
	colCode.Text = "Code";
	colCode.Width = 40;
	colCode.TextAlign = HorizontalAlignment.Center;

	ColumnHeader[] cols = { colPopulation, colCapital, colCode };
	lvwCountries.Columns.AddRange(cols);
}
 

Practical LearningPractical Learning: Creating Columns

  1. Display the first form if necessary and click its list view
  2. In the Properties window, click Columns and click its ellipsis button
  3. In the ColumnHeader Collection Editor, click Add
  4. In the columnHeader1 properties list, change the following properties
    (Name): colItemNumber
    Text: Item #
    Width: 70
  5. Click Add again and set the new column as follows:
    (Name): colCategory
    Text: Category
    Width: 70
  6. Click Add again and set the new column as follows:
    (Name): colItemName
    Text: Item Name
    Width: 200
  7. Click Add again and set the new column as follows:
    (Name): colItemSize
    Text: Size
    Width: 80
  8. Click Add again and set the new column as follows:
    (Name): colUnitPrice
    Text: Unit Price
    TextAlign: Right
  9. Click Add again and set the new column as follows:
    (Name): colQuantity
    Text: Qty
    TextAlign: Right
  10. Click OK
  11. While the list view is still selected in the form, change its View property to Details
      
  12. Execute the application to test it
  13. After viewing the form, close it

Column Insertion

If you call the AddRange() method, its list of columns is created at the end of any existing column, unless there was no other column. If you call the Add() method to create a column, the new column is added at the end of the existing columns, unless it is the first column. If you don't want the new column to simply be created at the end of the other column(s), if any, you can call the ColumnHeaderCollection.Insert() method. It is overloaded with two versions and their syntaxes are:

public void Insert(int index, ColumnHeader value);
public void Insert(int index, string str, int width, HorizontalAlignment textAlign);

In both versions, the first argument specifies the index where the new column will be created inside the Columns collection.

 

The Number of Columns of a List View

As reviewed above, the columns of a list view are stored in a collection. To know the number of columns of a list view, you can check its ColumnHeaderCollection.Count property.

Locating Columns

To find out if a certain column is part of a list view, you can call the ColumnHeaderCollection.Contains() method. Its syntax is:

public bool Contains(ColumnHeader value);

This method takes as argument a defined ColumnHeader object and scans the list of columns looking for it. If it finds it, it returns true. If it doesn't find a column that matches this object, it returns false. As opposed to looking for a column, you can perform two searches in one by calling the ColumnHeaderCollection.IndexOf() method. Its syntax is:

public int IndexOf(ColumnHeader value);

This method looks for the value ColumnHeader. If it finds it, it returns the column's index from the collection. If the method doesn't find it, it returns -1.

Deleting Columns

If you don't need a column any more, you can delete it. In the same way, you can delete all columns of a list view. To delete a ColumnHeader object, you can call the ColumnHeaderCollection.Remove() method. Its syntax is:

public virtual void Remove(ColumnHeader column);

To delete a column based on its position in the collection, you can call the ColumnHeaderCollection.RemoveAt() method. Its syntax is:

public virtual void RemoveAt(int index);

To delete all columns of a list view, you can call the ListView.ColumnHeaderCollection.Clear() method. Its syntax is:

public virtual void Clear();
 

The Sub Items of an Item

 

Introduction

The idea of having columns is to provide more information about each item of a list view instead of a simple string for each. Consider the following example:
private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width     = 420;
	lvwCountries.Height    = 100;
	lvwCountries.View      = View.Details;
	Controls.Add(lvwCountries);

	lvwCountries.Columns.Add("Name", 120, HorizontalAlignment.Left);
	ColumnHeader colArea = new ColumnHeader();
	colArea.Text = "Area";
	colArea.Width = 80;
	colArea.TextAlign = HorizontalAlignment.Right;
	lvwCountries.Columns.Add(colArea);

	ColumnHeader colPopulation = new ColumnHeader();
	colPopulation.Text = "Population";
	colPopulation.Width = 78;
	colPopulation.TextAlign = HorizontalAlignment.Right;

	ColumnHeader colCapital = new ColumnHeader();
	colCapital.Text = "Capital";
	colCapital.Width = 96;
	colCapital.TextAlign = HorizontalAlignment.Left;

	ColumnHeader colCode = new ColumnHeader();
	colCode.Text = "Code";
	colCode.Width = 40;
	colCode.TextAlign = HorizontalAlignment.Center;

	ColumnHeader[] cols = { colPopulation, colCapital, colCode };
	lvwCountries.Columns.AddRange(cols);
	 
	lvwCountries.Items.Add("Egypt");

	ListViewItem lviEngland = new ListViewItem("Portugal");
	lvwCountries.Items.Add(lviEngland);

	ListViewItem lviCountry = new ListViewItem("Australia");
	lvwCountries.Items.Add(lviCountry);
	lviCountry = new ListViewItem("Mali");
	lvwCountries.Items.Add(lviCountry);
	lviCountry = new ListViewItem("Sweden");
	lvwCountries.Items.Add(lviCountry);
}

Creating Sub Items

To support sub-items, the ListViewItem class is equipped with a property called SubItems. This property is of type ListViewSubItemCollection. To create a sub-item, you can directly specify its text by passing a string to the ListViewSubItemCollection.Add() method. The ListViewSubItemCollection.Add() method is overloaded with three versions. The version referred to in this case uses the following syntax:

public ListViewSubItem Add(string text);

To identify each piece of information concerning a sub-item, the ListViewSubItemCollection class is equipped with a property called Item, which in turn is based on the ListViewSubItem class. As you can see, the above Add() method returns a ListViewSubItem value.

Here are two examples of calling the above Add() method:
private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width     = 420;
	lvwCountries.Height    = 100;
	lvwCountries.View      = View.Details;
	Controls.Add(lvwCountries);

	lvwCountries.Columns.Add("Name", 120, HorizontalAlignment.Left);
	ColumnHeader colArea = new ColumnHeader();
	colArea.Text = "Area";
	colArea.Width = 80;
	colArea.TextAlign = HorizontalAlignment.Right;
	lvwCountries.Columns.Add(colArea);

	ColumnHeader colPopulation = new ColumnHeader();
	colPopulation.Text = "Population";
	colPopulation.Width = 78;
	colPopulation.TextAlign = HorizontalAlignment.Right;

	ColumnHeader colCapital = new ColumnHeader();
	colCapital.Text = "Capital";
	colCapital.Width = 96;
	colCapital.TextAlign = HorizontalAlignment.Left;

	ColumnHeader colCode = new ColumnHeader();
	colCode.Text = "Code";
	colCode.Width = 40;
	colCode.TextAlign = HorizontalAlignment.Center;

	ColumnHeader[] cols = { colPopulation, colCapital, colCode };
	lvwCountries.Columns.AddRange(cols);
	 
	ListViewItem lviEgypt = lvwCountries.Items.Add("Egypt");
	lviEgypt.SubItems.Add("1,001,450");
	lviEgypt.SubItems.Add("74,718,797");
	lviEgypt.SubItems.Add("Cairo");
	lviEgypt.SubItems.Add("eg");

	ListViewItem lviPortugal = new ListViewItem("Portugal");
	lviPortugal.SubItems.Add("92,391");
	lviPortugal.SubItems.Add("10,102,022");
	lviPortugal.SubItems.Add("Lisbon");
	lviPortugal.SubItems.Add("pt");
	lvwCountries.Items.Add(lviPortugal);

	ListViewItem lviCountry = new ListViewItem("Australia");
	lvwCountries.Items.Add(lviCountry);
	lviCountry = new ListViewItem("Mali");
	lvwCountries.Items.Add(lviCountry);
	lviCountry = new ListViewItem("Sweden");
	lvwCountries.Items.Add(lviCountry);
}

As mentioned above, each sub-item is of type ListViewSubItem. The ListViewSubItem class is equipped with three constructors. The default allows you to create an empty sub-item. After declaring a sub-item, you can specify its text by assigning the desired string to the ListViewSubItem.Text property. Instead of directly passing the text of a sub-item to the ListViewSubItemCollection.Add() method as done above, you can first define a ListViewSubItem object using the following constructor of the ListViewSubItem class:

public ListViewSubItem(ListViewItem owner, string text);

The first argument of this constructor specifies the ListViewItem object that this sub-item will belong to. The second argument is simply the string that this sub-item will display. After defining a ListViewSubItem object, you can pass it to the following version of the ListViewSubItemCollection.Add() method:

public ListViewSubItem Add(ListViewItem.ListViewSubItem item);

Here are three examples of using it:
private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width     = 420;
	lvwCountries.Height    = 100;
	lvwCountries.View      = View.Details;

	Controls.Add(lvwCountries);

	lvwCountries.Columns.Add("Name", 120, HorizontalAlignment.Left);
	ColumnHeader colArea = new ColumnHeader();
	colArea.Text = "Area";
	colArea.Width = 80;
	colArea.TextAlign = HorizontalAlignment.Right;
	lvwCountries.Columns.Add(colArea);

	ColumnHeader colPopulation = new ColumnHeader();
	colPopulation.Text = "Population";
	colPopulation.Width = 78;
	colPopulation.TextAlign = HorizontalAlignment.Right;

	ColumnHeader colCapital = new ColumnHeader();
	colCapital.Text = "Capital";
	colCapital.Width = 96;
	colCapital.TextAlign = HorizontalAlignment.Left;

	ColumnHeader colCode = new ColumnHeader();
	colCode.Text = "Code";
	colCode.Width = 40;
	colCode.TextAlign = HorizontalAlignment.Center;

	ColumnHeader[] cols = { colPopulation, colCapital, colCode };
	lvwCountries.Columns.AddRange(cols);
	 
	ListViewItem lviEgypt = lvwCountries.Items.Add("Egypt");
	lviEgypt.SubItems.Add("1,001,450");
	lviEgypt.SubItems.Add("74,718,797");
	lviEgypt.SubItems.Add("Cairo");
	lviEgypt.SubItems.Add("eg");

	ListViewItem lviPortugal = new ListViewItem("Portugal");
	lviPortugal.SubItems.Add("92,391");
	lviPortugal.SubItems.Add("10,102,022");
	lviPortugal.SubItems.Add("Lisbon");
	lviPortugal.SubItems.Add("pt");
	lvwCountries.Items.Add(lviPortugal);

	ListViewItem lviAustralia = new ListViewItem("Australia");
ListViewItem.ListViewSubItem subAustralia = new ListViewItem.ListViewSubItem(lviAustralia, "7,686,850");
	lviAustralia.SubItems.Add(subAustralia);
	subAustralia = new ListViewItem.ListViewSubItem(lviAustralia, "19,731,984");
	lviAustralia.SubItems.Add(subAustralia);
	subAustralia = new ListViewItem.ListViewSubItem(lviAustralia, "Canberra");
	lviAustralia.SubItems.Add(subAustralia);
	subAustralia = new ListViewItem.ListViewSubItem(lviAustralia, "au");
	lviAustralia.SubItems.Add(subAustralia);
	lvwCountries.Items.Add(lviAustralia);

	ListViewItem lviMali = new ListViewItem("Mali");
ListViewItem.ListViewSubItem subMali = new ListViewItem.ListViewSubItem(lviMali, "1.24 million");
	lviMali.SubItems.Add(subMali);
	subMali = new ListViewItem.ListViewSubItem(lviMali, "11,626219");
	lviMali.SubItems.Add(subMali);
	subMali = new ListViewItem.ListViewSubItem(lviMali, "Bamako");
	lviMali.SubItems.Add(subMali);
	subMali = new ListViewItem.ListViewSubItem(lviMali, "ml");
	lviMali.SubItems.Add(subMali);
	lvwCountries.Items.Add(lviMali);

	ListViewItem lviSweden = new ListViewItem("Sweden");
ListViewItem.ListViewSubItem subSweden = new ListViewItem.ListViewSubItem(lviSweden, "449,964");
	lviSweden.SubItems.Add(subSweden);
	subSweden = new ListViewItem.ListViewSubItem(lviSweden, "8,878,085");
	lviSweden.SubItems.Add(subSweden);
	subSweden = new ListViewItem.ListViewSubItem(lviSweden, "Stockholm");
	lviSweden.SubItems.Add(subSweden);
	subSweden = new ListViewItem.ListViewSubItem(lviSweden, "se");
	lviSweden.SubItems.Add(subSweden);
	lvwCountries.Items.Add(lviSweden);
}

If you call the ListViewSubItemCollection.Add() method to create a sub-item, the new one would be added to end of the list. If you want, you can insert the new sub-item somewhere inside the collection. To do this, you would call the ListViewCubItemCollection.Insert() method. Its syntax is:

public void Insert(int index, ListViewItem.ListViewSubItem item);

The first argument is the index that the new sub-item will occupy after being inserted. The second argument is the sub-item to create.

Practical LearningPractical Learning: Creating Sub-Items

  1. Display the New Store Item form and change its design as follows:
     
    Control Name Text Other Properties
    Label   Category:  
    ComboBox cboCategories Miscellaneous Modifiers: Public
    Items: Babies, Teens, Women, Men, Miscellaneous
    Label   Item Name:  
    TextBox txtItemName    
    Label   Item Size:  
    TextBox txtItemSize    
    Label   Quantity:  
    TextBox txtQuantity    
    Label   Unit Price:  
    TextBox txtUnitPrice   TextAlign: Right
    Label   Item #:  
  2. Display the first form and double-click its New Item button
  3. Change its Click event as follows:
     
    private void btnNewItem_Click(object sender, System.EventArgs e)
    {
    	NewStoreItem frmItem = new NewStoreItem();
    	int icoSelected = 4;
    
    	Random rndNumber = new Random(DateTime.Now.Millisecond);
    	int number1 = rndNumber.Next(100, 999);
    	int number2 = rndNumber.Next(100, 999);
    	String itemNumber = number1 + "-" + number2;
    
    	frmItem.txtItemNumber.Text = itemNumber;
    	if( frmItem.ShowDialog() == DialogResult.OK )
    	{
    		string strCatSelected = frmItem.cboCategories.Text;
    		string strItemName    = frmItem.txtItemName.Text;
    		string strItemSize    = frmItem.txtItemSize.Text;
    		string strQuantity    = frmItem.txtQuantity.Text;
    		string strUnitPrice   = frmItem.txtUnitPrice.Text;
    		string strItemNumber  = frmItem.txtItemNumber.Text;
    
    		 // If the user didn't provide a name for the item,
    		 // don't do anything
    		 if( strItemName == "" )
    			 return;
    
    		 // Make sure the user entered a unit price
    		 if( strItemNumber == "" )
    			 return;
    
    		if( strCatSelected.Equals("Babies") )
    			icoSelected = 0;
    		else if( strCatSelected.Equals("Teens") )
    			icoSelected = 1;
    		else if( strCatSelected.Equals("Women") )
    			icoSelected = 2;
    		else if( strCatSelected.Equals("Men") )
    			icoSelected = 3;
    
    ListViewItem lviStoreItem = new ListViewItem(frmItem.txtItemNumber.Text, icoSelected);
    		lviStoreItem.SubItems.Add(strCatSelected);
    		lviStoreItem.SubItems.Add(strItemName);
    		lviStoreItem.SubItems.Add(strItemSize);
    		lviStoreItem.SubItems.Add(strUnitPrice);
    		lviStoreItem.SubItems.Add(strQuantity);
    		this.lvwStoreItems.Items.Add(lviStoreItem);
    	}
    }
  4. Execute the application and create a few items as follows (let the computer generate store numbers):
      
    Category Item Name Size Unit Price Qty
    Women Cashmere Lined Glove 8 115.95 12
    Miscellaneous Chocolate Gift Box Medium 45.00 5
    Men Trendy Jacket Medium 45.85 8
    Women Stretch Flare Jeans Petite 27.75 6
    Women Belted Sweater L 15.95 10
    Teens Girls Classy Handbag One Size 95.95 4
    Women Casual Dress Shoes 9.5M 45.95 16
    Babies Infant Girls Ballerina Dress 12M 22.85 14
    Teens Girls Velour Dress 10 12.55 8
    Women Lace Desire Panty M 7.15 22
    Teens Boys Hooded Sweatshirt M (7/8) 15.95 6
    Men Classic Pinstripe Suit 38 145.95 8
     
  5. Close the form and return to your programming environment

Managing Sub Items

When you create a new sub-item, it uses a default font and a black color on a white background. If you want, you can change the way a sub-item aesthetically displays. To allow these changes, the ListViewItem class is equipped with the UseItemStyleForSubItems Boolean property, whose default value is true. When this property is set to true, the compiler refers to the item that "owns" the current sub-item to paint the sub-item, as we will see in the next section. If you plan to change these aspects, you must first set this property to false.

After setting the ListViewItem.UseItemStyleForSubItems property to false, you can set the following properties of the ListViewSubItem class as you wish:

To restore these settings on the sub-item, you can call the ListViewItem.ListViewSubItem.ResetStyle() method. Its syntax is:

public void ResetStyle();

When called, this method resets the font, the text color, and the background color.

Managing Items of a List View

 

The Font, Text Color, and Background of an Item

After adding an item to a list view, the new item assumes some default styles involving the font, the color, and the background. To enhance the appearance of the items, you can change these characteristics that are primarily controlled by the ListViewItem.UseItemStyleForSubItems Boolean property. Its default value is true. You can use it to change the properties of an item as follows:

 

Practical LearningPractical Learning: Applying Aesthetic Effects

  1. In the first form file, declare a static integer named rowCurrent and initialize it to 2
     
    public class Form1 : System.Windows.Forms.Form
    {
    	static int rowCurrent = 2;
    
    	. . .
  2. To apply aesthetic effects, change the Click event of the New Item button as follows:
     
    private void btnNewItem_Click(object sender, System.EventArgs e)
    {
    	NewStoreItem frmItem = new NewStoreItem();
    	int icoSelected = 4;
    
    	Random rndNumber = new Random(DateTime.Now.Millisecond);
    	int number1 = rndNumber.Next(100, 999);
    	int number2 = rndNumber.Next(100, 999);
    	String itemNumber = number1 + "-" + number2;
    
    	frmItem.txtItemNumber.Text = itemNumber;
    	if( frmItem.ShowDialog() == DialogResult.OK )
    	{
    		string strCatSelected = frmItem.cboCategories.Text;
    		string strItemName    = frmItem.txtItemName.Text;
    		string strItemSize    = frmItem.txtItemSize.Text;
    		string strQuantity    = frmItem.txtQuantity.Text;
    		string strUnitPrice   = frmItem.txtUnitPrice.Text;
    		string strItemNumber  = frmItem.txtItemNumber.Text;
    
    		 // If the user didn't provide a name for the item,
    		 // don't do anything
    		 if( strItemName == "" )
    			 return;
    
    		 // Make sure the user entered a unit price
    		 if( strItemNumber == "" )
    			 return;
    
    		if( strCatSelected.Equals("Babies") )
    			icoSelected = 0;
    		else if( strCatSelected.Equals("Teens") )
    			icoSelected = 1;
    		else if( strCatSelected.Equals("Women") )
    			icoSelected = 2;
    		else if( strCatSelected.Equals("Men") )
    			icoSelected = 3;
    
    	ListViewItem lviStoreItem = new ListViewItem(frmItem.txtItemNumber.Text, icoSelected);
    		if( rowCurrent % 2 == 0 )
    		{
    			lviStoreItem.BackColor = Color.FromArgb(255, 155, 0);
    			lviStoreItem.ForeColor = Color.White;
    		}
    		else
    		{
    			lviStoreItem.BackColor = Color.FromArgb(255, 215, 150);
    			lviStoreItem.ForeColor = Color.Black;
    		}
    		lviStoreItem.SubItems.Add(strCatSelected);
    		lviStoreItem.SubItems.Add(strItemName);
    		lviStoreItem.SubItems.Add(strItemSize);
    		lviStoreItem.SubItems.Add(strUnitPrice);
    		lviStoreItem.SubItems.Add(strQuantity);
    		this.lvwStoreItems.Items.Add(lviStoreItem);
    	}
    
    	rowCurrent++;
    }
  3. Execute the application and test the form by creating four different records
     
  4. Close the form and return to your programming environment

Locating a List View Item

The items of a list view are stores in a collection represented by the ListView.Items property. To know the number of items in the list, you can retrieve the value of the ListViewItemCollection.Count property. Each member of this collection has an index represented by the ListViewItemCollection.Index property.

You can also locate an item using the coordinates of a point inside its bounding area. To use this technique, you can call the GetItemAt() method of the ListView class. Its syntax is:

public ListViewItem GetItemAt(int x, int y);

This method expects the coordinates (x, y) of a point. If an item is found at that point, this method returns it. If there is no item at that point, the method returns 0.

Deleting Items

To delete an item from a list view, you can call the ListViewItemCollection.Remove() method. Its syntax is:

public virtual void Remove(ListViewItem item);

This method takes as argument the ListViewItem object to be deleted. If you are already positioned at that item, you can call its own ListViewItem.Remove() method. Its syntax is:

public virtual void Remove();

To delete an item based on its index, you can call the ListViewItemCollection.RemoveAt() method whose syntax is:

public virtual void RemoveAt(int index);

When calling this method, you must pass the index of the undesired item. If the item is found, it would be deleted. If you provide a negative index or one that is higher than the ListViewItemCollection.Count property, the compiler would throw an ArgumentOutOfRangeException exception.

To delete all items from a list view, you can call the ListViewItem.Clear() method. Its syntax is:

public virtual void Clear();

When called, this method removes all items of the list view.

 

Characteristics of a List View

 

Column Header Style

If you create the columns of a list view, when the user displays the detail view, the column headers appear and behave like regular buttons. This also means that the user can click a column header and you can take action. If you don't want this appearance and this behavior, you can make the columns appear flat. This characteristics is controlled by the HeaderStyle property of the ListView class. This property is based on the ColumnHeaderStyle enumerator. Its members are:

  • Clickable: This is the default style. The columns headers appear and behave like buttons:
     
    lvwCountries.HeaderStyle = ColumnHeaderStyle.Clickable;
  • Nonclickable: The columns are flat and don't change their appearance when the user clicks one:
     
    lvwCountries.HeaderStyle = ColumnHeaderStyle.Nonclickable;
  • None: No column header appears:
     
    lvwCountries.HeaderStyle = ColumnHeaderStyle.None;

Selecting Items in a List View

To select an item in the list, the user can click it. The selected item indicates this by being highlighted. To select another item, the user can click it and this automatically dismisses the previous selection. If you want, you can give the user the ability to select more than one item or you can prevent the user from selecting more than one item. This characteristic is controlled by the MultiSelect property of the ListView class. Its default value is true, which allows the user to select one or more items. If you set it to false, the user can select only one item at a time.

You can also allow the user to select an item by positioning the mouse over it. This characteristic is controlled by the HoverSelection property of the ListView class.

When an item has been selected or more than one item are selected, the selected items are stored in a list represented by the SelectedItems property of the ListView class. The ListView.SelectedItems property is an object based on the ListView.SelectedListViewItemCollection class. If the ListView.MultiSelect property is set to false, this collection would contain only one item.

The number of items selected in the control is known as the Count property of the SelectedListViewItemCollection class. Each item selected can be identified through the Item indexed property of the SelectedListViewItemCollection class.

The SelectedListViewItemCollection class holds a list of the objects that are selected and each is identified as a ListViewItem. If you are more interested in the positions of the items selected and not necessarily their objects, you can use the SelectedIndices property of the ListView class. Each item selected has its index stored in this list. The ListView.SelectedIndices property is based on the ListView.SelectedIndexCollection class.

After selecting an item, if the user clicks another control, the item that was selected would not be highlighted anymore. If you want the control to continue showing the current selection even when the list view loses focus, set the value of the HideSelection Boolean property of the ListView class accordingly.

Practical LearningPractical Learning: Managing List View Items

  1. Display the first form and click its list view
  2. In the Events section of the Properties window, double-click the right field to DoubleClick and implement the event as follows:
     
    private void lvwStoreItems_DoubleClick(object sender, System.EventArgs e)
    {
    	if( this.lvwStoreItems.SelectedItems.Count == 0 ||
                        this.lvwStoreItems.SelectedItems.Count > 1 )
    		return;
    
    	ListViewItem lviCurrent = this.lvwStoreItems.SelectedItems[0];
    
    	NewStoreItem frmItem = new NewStoreItem();
    
    	frmItem.txtItemNumber.Text = lviCurrent.Text;
    	frmItem.cboCategories.Text = lviCurrent.SubItems[1].Text;
    	frmItem.txtItemName.Text   = lviCurrent.SubItems[2].Text;
    	frmItem.txtItemSize.Text   = lviCurrent.SubItems[3].Text;
    	frmItem.txtUnitPrice.Text  = lviCurrent.SubItems[4].Text;
    	frmItem.txtQuantity.Text   = lviCurrent.SubItems[5].Text;
    			 
    	if( frmItem.ShowDialog() == DialogResult.OK )
    	{
    		this.lvwStoreItems.SelectedItems[0].Text = frmItem.txtItemNumber.Text;
    		this.lvwStoreItems.SelectedItems[0].SubItems[1].Text = frmItem.cboCategories.Text;
    		this.lvwStoreItems.SelectedItems[0].SubItems[2].Text = frmItem.txtItemName.Text;
    		this.lvwStoreItems.SelectedItems[0].SubItems[3].Text = frmItem.txtItemSize.Text;
    		this.lvwStoreItems.SelectedItems[0].SubItems[4].Text = frmItem.txtUnitPrice.Text;
    		this.lvwStoreItems.SelectedItems[0].SubItems[5].Text = frmItem.txtQuantity.Text;
    	}
    }
  3. Return to the form. Under the form, click contextMenu1.
    In the form, click Context Menu and click Edit
  4. In the Events section of the Properties window, click Click and select lvwStoreItems_DoubleClick
  5. In the form and in the Context Menu group, double-click Delete  and implement its event as follows:
     
    private void mnuDelItem_Click(object sender, System.EventArgs e)
    {
    	if( this.lvwStoreItems.SelectedItems.Count == 0 )
    		return;
    
    	System.Windows.Forms.DialogResult answer = 
    		MessageBox.Show("Are you sure you want to remove this item from the inventory?",
    		"Delete Warning",
    		MessageBoxButtons.YesNoCancel,
    		MessageBoxIcon.Question);
    	if( answer == DialogResult.Yes )
    		this.lvwStoreItems.SelectedItems[0].Remove();
    }
  6. On the form and in the Context Menu group, double-click Remove all Items and implement its event as follows:
     
    private System.Void mnuDeleteAll_Click(System.Object   sender, System.EventArgs   e)
    {
    	 
    }
  7. Save all

Full Row Selection

By default, to select an item, the user must click the item itself and not one of its sub-items. If you want an item and its sub-items to be selected when the user clicks anything on their line, you can change the value of the ListView.FullRowSelect Boolean property. Its default value is set to false, which obliges the user to click the item itself. If you set this property to true, the whole row would be highlighted when either you or the user selects it.

Practical Learning Practical Learning: Allowing Full Row Selection

  1. To allow the user to select a whole when clicking an item, set the list view's FullRowSelect property to True
  2. Save all

Grid Lines

When using the detail view, to make a list view more indicative, you can underline each row. This characteristic is controlled by the GridLines Boolean property of the ListView class. The default value of this property is false. If you set it to true, horizontal grid lines would appear among items throughout the list view, including empty rows:

lvwCountries.GridLines = true;
 

Practical Learning Practical Learning: Writing Code For a Toolbar

  1. To display grid lines, set the list view's GridLines property to true
  2. Execute the application and create the list of items we had earlier
     
  3. Close the form(s)

List Items and Check Boxes

Besides, or instead of, icons, you can display check boxes with the items of a list view. This characteristic is controlled by the CheckBoxes property. Its default value is false, which omits displaying the check boxes. If you set it to true, a check box would appear on the left of each item of the list view:

private void btnCreate_Click(object sender, System.EventArgs e)
{
	ListView lvwCountries = new ListView();
	lvwCountries.Location  = new Point(10, 40);
	lvwCountries.Width     = 420;
	lvwCountries.Height    = 100;
	lvwCountries.View      = View.Details;
	lvwCountries.CheckBoxes = true;

	Controls.Add(lvwCountries);

	. . .
}
 

Home Copyright © 2004-2010 FunctionX, Inc.