Home

Windows Controls: The List View

   

Introduction to the List View

 

Description

A list view is a list of items that presents many options:

  • The items can each appear as a large icon and a label
     
    List View: Large Icons
  • The items can each appear as a small icon and a label:
     
    List View: List
  • The items can be made to show some details (related-information) each:
      
    List View Style: Small Icons

ApplicationApplication: Introducing the List View Control

  1. Start Microsoft Visual C#
  2. To create a new application, on the main menu, click File -> New Project
  3. In the middle list, click Windows Forms Application
  4. Change the Name to AltairRealtors1
  5. Click OK
  6. To create a new class, on the main menu, click Project -> Add Class...
  7. Set the Name to RealEstateProperty
  8. Click Add
  9. Change the file as follows:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace AltairRealtors1
    {
        [Serializable]
        public class RealEstateProperty
        {
            public string PropertyNumber { get; set; }
            public string PropertyType { get; set; }
            public string City { get; set; }
            public string State { get; set; }
            public short  Stories { get; set; }
            public int    YearBuilt { get; set; }
            public short  Bedrooms { get; set; }
            public float  Bathrooms { get; set; }
            public string Condition { get; set; }
            public string Status { get; set; }
            public double MarketValue { get; set; }
            public string PictureFile { get; set; }
        }
    }
  10. In the Solution Eplorer, right-click Form1.cs and click Rename
  11. Type AltairRealtors.cs and press Enter twice tp display the form
  12. Double-click the body of the form
  13. Change the file as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace AltairRealtors1
    {
        public partial class AltairRealtors : Form
        {
            List<RealEstateProperty> properties;
    
            public AltairRealtors()
            {
                InitializeComponent();
            }
    
            private void AltairRealtors_Load(object sender, EventArgs e)
            {
                properties = new List<RealEstateProperty>();
                ShowProperties();
            }
    
            private void ShowProperties()
            {
    
            }
        }
    }
  14. Return to the form

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 list view button. To add a list view to your application, you can click list view 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:

using System;
using System.Drawing;
using System.Windows.Forms;

public class Exercise : System.Windows.Forms.Form
{
    ListView lvwCountries;

    public Exercise()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        Text = "Countries Statistics";
        Size = new Size(452, 218);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 160;

        Controls.Add(lvwCountries);
    }
}

public class Program
{
    static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

Countries Statistics

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

ApplicationApplication: Creating a List View

  1. On the Toolbox, click Common Controls and click ListView
  2. Click the form
  3. Complete the design of the form as follows:
     
    Altair Realtors
    Control (Name) Anchor BorderStyle SizeMode  Text 
    ListView DataGridView lvwProperties Top, Bottom, Left, Right      
    PictureBox pbxPicture Bottom, Right FixedSingle  Zoom   
    Button btnNewProperty  Bottom, Left     New Property... 
    Button btnClose Bottom, Right      Close
    Form
    Text: Altair Realtors - Properties Listing
    StartPosition: CenterScreen

Introduction to the Items of a List View

 

The Collection of List View Items

The items of a list view are stored in a property called Item, which is of type ListViewItemCollection. The ListViewItemCollection class implements the IList, the ICollection, and the IEnumerable interfaces.

Visually Creating the Items of a List View

To visually create the items of a list view, you can use the ListViewItem Collection Editor of Microsoft Visual Studio. To access it, after adding a list view object to your application:

  • On the form, right-click the list view and click Edit Items...
  • While the list view is selected on the form:
    • in the Properties window, click Items, and click its ellipsis button
    • Under the Properties window, click Edit Items...

In both cases, the ListViewItem Collectin Editor would come up:

ListViewItem Collection Editor

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

ApplicationApplication: Adding Items to a List View

  1. On the form, right-click the list view and click Edit Items...
  2. Click Add...
  3. In the Members list, make sure the new item is selected.
    In the right list, click Text and type 297-409
  4. Click Add
  5. In the right list, click Text and type 712-474
     
    ListViewItem Collection Editor
  6. Click OK

Programmatically Creating an Item

To help you programmatically create a new 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 InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(452, 214);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 160;

        lvwCountries.Items.Add("Egypt");

        Controls.Add(lvwCountries);
}

This would produce:

Countries Statistics

As the Items property is in fact a collection, each item 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 detail.

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 InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(452, 214);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 160;

        lvwCountries.Items.Add("Egypt");

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

        Controls.Add(lvwCountries);
}

Countries Statistics

ApplicationApplication: Creating List View Items

  1. To create a new form, on the main menu, click Projects -> Add Windows Form...
  2. Set the Name to PropertyEditor
  3. Click Add
  4. In the Dialogs section of the Toolbox, click OpenFileDialog
  5. Click the form
  6. In the Properties window, change its characteristics as follows:
    (Name): dlgPicture
    DefaultExt: jpg
    Filter: JPEG Files (*.jpg,*.jpeg)|*.jpg
    Title: Select House Picture
  7. Design the form as follows:
     
    Altair Realtors
    Control (Name) Text Other Properties
    Label Label   Property Type:  
    ComboBox ComboBox cbxPropertyTypes   DropDownStyle: DropDownList
    Modifiers: Public
    Items: Condominium
    Townhouse
    Single Family
    Unknown
    Label Label   City:  
    TextBox TextBox txtCity   Modifiers: Public
    Label Label   State:  
    ComboBox ComboBox cbxStates   DropDownStyle: DropDownList
    Modifiers: Public
    Items:
    AL, AK, AZ, AR, CA, CO, CT, DE, DC, FL, GA, HI, ID, IL, IN, IA, KS, KY, LA, ME, MD, MA, MI, MN, MS, MO, MT, NE, NV, NH, NJ, NM, NY, NC, ND, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VT, VA, WA, WV, WI, WY
    Label Label   Stories:  
    TextBox TextBox txtStories   Modifiers: Public
    Label Label   Year Built:  
    TextBox TextBox txtYearBuilt   Modifiers: Public
    Label Label   Bedrooms:  
    TextBox TextBox txtBedrooms 0 Modifiers: Public
    Label Label   Bathrooms:  
    TextBox TextBox txtBathrooms 0.00 Modifiers: Public
    Label Label   Property #:  
    TextBox TextBox txtPropertyNumber   Enabled: False
    Modifiers: Public
    Label Label   Condition:  
    ComboBox ComboBox cbxConditions   DropDownStyle: DropDownList
    Modifiers: Public
    Items:
    Excellent
    Good Shape
    Needs Fixing
    Label Label   Market Value:  
    TextBox TextBox txtMarketValue 0.00 Modifiers: Public
    Label Label   Status:  
    ComboBox ComboBox cbxStatus   DropDownStyle: DropDownList
    Modifiers: Public
    Items:
    Unspecified
    Available
    Sold
    Button Button btnPicture Picture...  
    PictureBox PictureBox pbxPicture   BorderStyle: FixedSingle SizeMode: Zoom
    Button Button btnOK OK DialogResult: OK
    Button Button btnCancel Cancel DialogResult: Cancel
    Form
    FormBorderStyle: FixedDialog
    Text: Altair Realtors - Property Editor
    StartPosition: CenterScreen
    AcceptButton: btnOK
    CancelButton: btnCancel
    MaximizeBox: False
    MinimizeBox: False
    ShowInTaskBar: False
  8. Double-click an unoccupied area of the form
  9. Return to the form
  10. Double-click the Picture button
  11. Change the file as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace AltairRealtors1
    {
        public partial class PropertyEditor : Form
        {
            public string pictureFile;
    
            public PropertyEditor()
            {
                InitializeComponent();
            }
    
            private void PropertyEditor_Load(object sender, EventArgs e)
            {
                pictureFile = "";
            }
    
            private void btnPicture_Click(object sender, EventArgs e)
            {
                if (dlgPicture.ShowDialog() == DialogResult.OK)
                {
                    pbxPicture.Image = Image.FromFile(dlgPicture.FileName);
                    pictureFile = dlgPicture.FileName;
                }
            }
        }
    }
  12. On the main menu, click Window -> AltairRealtors.cs [Design]*
  13. On the form, double-click the New Property button
  14. Implement the event as follows:
    private void btnNewProperty_Click(object sender, EventArgs e)
    {
        PropertyEditor editor = new PropertyEditor();
    
        Random rndNumber = new Random(DateTime.Now.Millisecond);
        int number1 = rndNumber.Next(100, 999);
        int number2 = rndNumber.Next(100, 999);
        string propNumber = number1 + "-" + number2;
    
        editor.txtPropertyNumber.Text = propNumber;
    
        if( editor.ShowDialog() == DialogResult.OK )
        {
            ListViewItem lviStoreItem = new ListViewItem(editor.txtPropertyNumber.Text);
            lvwProperties.Items.Add(lviStoreItem);
        }
    }
  15. To execute the application, press F5
  16. When the form displays, click the New Property button
  17. When the dialog box comes up, click OK
  18. Close the form and return to your programming environment

Adding a Range of Items

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 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 InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(452, 214);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 160;

        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);

        Controls.Add(lvwCountries);
}

Countries Statistics

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

public ListViewItem(string[] items);

Grouping the Items of a List View

 

Introduction

To better organize the items of a list view, you can put them in groups. Each group can hold a different set of items and/or a different number of items, but all items must be of the same type.

To support groups, the ListView class is equipped with a property named Groups. This property is based on an enumeration named ListViewGroupCollection:

public ListViewGroupCollection Groups { get; }

ListViewGroupCollection is a classic collection class that implements the IList, the ICollection, and the IEnumerable interfaces, which give it the ability to add and manage groups.

public class ListViewGroupCollection : IList, 
                                       ICollection,
                                       IEnumerable

Creating a Group of Items

To support a group of items, the .NET Framework provides a class named ListViewGroup.

To visually create a group:

  • On the form, right-click the list view and click Edit Groups...
  • While the list view is selected on the form:
    • In the Properties window, click Groups, then click its ellisis button
    • Under the Properties window, click Edit Groups...

Any of these actions would display the ListViewGroup Collection Editor:

ListViewGroup Collection Editor

To create a group, click Add. In the same way, you can create as many groups as you want. After creating them, click OK.

Characteristics of a Group of Items

The items that belong to a group must make it obvious. To start, the group must identify itself, which is done with a title or label. The title of a group is also called a header. This is represented by the Header property.

Besides a title, a group has a name, which is represented by the Name property.

By default, when the title displays, it is aligned to the left. If you want, you can position it either to the center or the right section. The alignment is controlled by the HeaderAlignment property that is of type HorizontalAlignment.

Applying a Group to an Item

After creating the groups, you can assign one to any item of your choice. To do this visually, display the ListViewItem Collection Editor. If you had not yet created the items, you must first do that. In the Members list, click an item. In the right list, click Group, then click the arrow of its combo box, and select a group of your choice.

To let you get a list of items that belong to a group, the ListViewGroup class is equipped with a property named Items. This property is of type ListViewItemCollection:

public ListView..::..ListViewItemCollection Items { get; }

To know the list view that a group belongs to, get the value of the ListView property, which is of type ListView:

public ListView ListView { get; }

ApplicationApplication: Creating a Group of Items

  1. Right-click the form and click Edit Groups...
  2. Click Add
  3. Click Header and type Condominium
  4. Click Name and type Condominium
  5. Click Add
  6. Click Header and type Townhouse
  7. Click Name and type Townhouse
  8. Click Add
  9. Click Header and type Single Family
  10. Click Name and type SingleFamily

    ListViewGroup Collection Editor
  11. Click OK
  12. On the form, right-click the list view and click Edit Items...
  13. In the Members list, click the first item.
    In the right list, click Group, then click the arrow of its combo box and select Single Family
  14. In the Members list, click the second item
  15. In the right list, click Group, then click the arrow of its combo box and select Condominium
  16. Click OK

The Styles of a List View

 

Introduction

A list view provides various options to display its items. To support this, the ListView class is equipped with the View property that is based on the View enumeration. Its members are:

  • LargeIcon: In this view, the control displays a list of items in the order they were added from left to right and from top to bottom. This means that items start displaying on the top left section of the control to right. When the first line is filled and there are still items, the list continues to the next line. Each item uses a square size corresponding to a 32x32 pixel
  • SmallIcon: Like the LargeIcon style, this view displays the list of items from the left to the right then to the next line if necessary. This time, each item uses a square region corresponding to a 16x16 pixel size
  • List: Like the SmallIcon option, each item uses a 16x16 pixel square to display. This time, the list is arranged in columns: the first item appears to the left side of the control. 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
  • Details: In this view, instead of showing just the string of the (main) item, each item can provide more detailed information in a column

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.

ApplicationApplication: Using View Styles

  1. To create an icon, on the main menu, click Project -> Add New Item...
  2. In the middle list, click Icon File
  3. Set the Name to LargeIcon and click Add
  4. Design the 16x16 pixels version of the icon as follows:
     
    Icon Design
  5. Design the 32x32 pixels version of the icon as follows:
     
    Icon Design
  6. On the main menu, click Project -> Add New Item...
  7. In the middle list, click Icon File
  8. Set the Name to SmallIcon and click Add
  9. Design the 16x16 pixels version of the icon as follows:
     
  10. Design the 32x32 pixels version of the icon as follows:
     
    Icon  Design
  11. On the main menu, click Project -> Add New Item...
  12. In the middle list, click Icon File
  13. Save the Name to List and click Add
  14. Design the 16x16 version as follows:
     
    Icon Design
  15. Design the 32x32 version as follows:
     
    Icon Design
  16. On the main menu, click Project -> Add New Item...
  17. In the middle list, click Icon File
  18. Save the Name to Details and click Add
  19. Design the 16x16 version as follows:
     
    Icon Design
  20. Design the 32x32 version as follows:
     
    Icon Design
  21. Change the design of the form as follows:
     
    Altair Realtors
    Control (Name) Image
    Button btnLargeIcons LargeIcons.ico
    Button btnSmallIcons SmallIcons.ico
    Button btnList List.ico
    Button btnDetails Details.ico
  22. Double-click the left button and implement its event as follows:
    private void btnLargeIcons_CheckedChanged(object sender, EventArgs e)
    {
        lvwProperties.View = View.LargeIcon;
    }
  23. Return to the form
  24. Double-click the second button from left and implement its event as follows:
    private void btnSmallIcons_CheckedChanged(object sender, EventArgs e)
    {
         lvwProperties.View = View.SmallIcon;
    }
  25. Return to the form
  26. Double-click the third button from left and implement its event as follows:
    private void btnList_CheckedChanged(object sender, EventArgs e)
    {
         lvwProperties.View = View.List;
    }
  27. Return to the form
  28. Double-click the second button from right and implement its event as follows:
    private void btnDetails_CheckedChanged(object sender, EventArgs e)
    {
         lvwProperties.View = View.Details;
    }
  29. Return to the form
  30. Double-click the Close button and implement its Click events as follows:
    private void btnClose_Click(object sender, EventArgs e)
    {
         Close();
    }
  31. Return to the form
  32. To execute the application, press F5
  33. Click the buttons on the form
  34. Close the form and return to your programming environment

The Icons of List View Items

A list view has built-in capability to display icons. The list view uses two sets of pictures in either 16x16 pixels or larger than that. This means that two icons would be associated to each item.

The first category of icons should have a 16x16 pixels size. These are referred to as small icons. In the second category of pictures, one of the types uses a 32x32 pixels size. In Microsoft Windows 7, the set of 32x32 pixels list is referred to as medium icons. In the .NET Framework, these are referred to as large icons.

Before using the pictures, you should 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 named LargeImageList for the 32x32-pixel icons and another property named SmallImageList for the 16x16-pixel icons. After creating both ImageList objects, you can assign each to the appropriate property.

After assigning the icons to the list view items, each view style can use the appropriate item to display:

  • LargeIcon: In this view, each item is displayed with its assigned 32x32 pixels icon. The string of the item displays under its corresponding icon:
     
    List View: Large Icons
  • List: Each item appears with the 16x16 pixels small icon to its left:
     
    List View: List
  • SmallIcon: Same as the List option
  • Details: Same as the List option

ApplicationApplication: Associating Icons With Nodes

  1. To create an icon, on the main menu, click Project -> Add New Item...
  2. In the middle list, click Icon File
  3. Set the Name to Condominium and click Add
  4. Design the 16x16 icon as follows:
     
    Icon Design
  5. In the left frame, click 32x32
  6. Design the icon as follows:
     
    Icon Design
  7. On the main menu, click File -> Close
  8. When asked whether you want to save, click Yes
  9. On the main menu, click Project -> Add New Item...
  10. In the middle list, click Icon File
  11. Set the Name to Townhouseand click Add
  12. Design the 16x16 icon as follows:
     
    Icon Design
  13. In the left frame, click 32x32
  14. Design the icon as follows:
     
    Icon Design
  15. On the main menu, click File -> Close
  16. When asked to save, click Yes
  17. On the main menu, click Project -> Add New Item...
  18. In the middle list, click Icon File
  19. Set the Name to SingleFamily and click Add
  20. Design the 16x16 icon as follows:
     
    Icon Design
  21. In the left frame, click 32x32
  22. Design it as follows:
     
    Icon Design
  23. On the main menu, click File -> Close
  24. When asked to save, click Yes
  25. In the Solution Explorer, double-click RealEstate.cs to display the form
  26. In the Component section of the Toolbox, click ImageList
  27. Click the form
  28. In the Properties window, click (Name) and type imgLarge
  29. Change the ImageSize to 32, 32
  30. Click the ellipsis button of the Images field
  31. In Image Collection Editor, click Add
  32. Locate the folder that contains the current project and display it in the Look In combo box
  33. Select Condominium.ico and click Open
  34. In the same way, add the Townhouse.ico icon and the SingleFamily.ico icon
  35. Click OK
  36. In the Components section of the Toolbox, click ImageList
  37. Click the form
  38. In the Properties window, change its name to imgSmall
  39. In the Properties window, click the ellipsis button of the Images field
  40. In Image Collection Editor, click Add
  41. Select Condominium.ico, Townhouse.ico, and SingleFamily.ico
  42. Click OK
  43. On the form, click the list view
  44. In the Properties window, Set LargeImageList to imgLarge
  45. Set the SmallImageList property to imgSmall
  46. Click Items and click its ellipsis button
  47. In the Members list, click the first item if necessary.
    In the right list, click ImageIndex, then click the arrow of its combo box and select 2
  48. In the Members list, click the second item
  49. In the right list, click ImageIndex, then click the arrow of its combo box and select 0
  50. Click OK
  51. To execute, press F5
  52. Click the buttons to see the results
  53. After using the form, close it and return to your programming environment
  54. On the form, click the list view
  55. In the Properties window, click View, then click the arrow of is combo box and select Details

The Columns of a List View

 

Introduction

One of the characteristics of a list view is that it can provide more information about each item of its list. Each type of item can be equipped with its own list of sub-items. The view would appear as follows:

List View Style: Details

Before creating the sub-items of a list view, you may need to plan them 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.

Visually Creating Columns

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.

At design time, to create the columns:

  • On the form, right-click the list view and click Edit Columns...
  • On the form, click the list view to select it
    • In the Properties window, click Columns, then click its ellispsis button
    • Under the Properties window, click Edit Columns...

This would open the ColumnHeader Collection Editor:

ColumnHeader Collection Editor

To create a column, you can click Add. In the right Properties list, you can click Text and type the string that would display on the column header.

ApplicationApplication: Visually Creating Columns

  1. On the form, right-click the list view and click Edit Columns...
  2. Click Add
  3. While the new item is still selected, in the right list, click Text and type Property #

Programmatically Creating Columns

To programmatically 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 InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(452, 214);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 160;

        lvwCountries.View = View.Details;
        lvwCountries.Columns.Add("Name", 120, HorizontalAlignment.Left);

        Controls.Add(lvwCountries);
}

This would produce:

As mentioned earlier, a column is in fact an object of type ColumnHeader. This class is equipped with all the necessary characteristics that define 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 InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(452, 214);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 100;

        lvwCountries.View = View.Details;
        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);

        Controls.Add(lvwCountries);
}

This would produce:

Countries Statistics

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 InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(452, 214);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 100;

        lvwCountries.View = View.Details;
        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);

        Controls.Add(lvwCountries);
}

This would produce:

Countries Statistics

ApplicationApplication: Creating Columns

  1. In the ColumnHeader Collection Editor, while the new item is still selected in the Members list, in the right list, click (Name) and type colPropertyNumber
  2. Click Width and type 70
  3. Click Add
  4. Create the other columns as follows:
     
    (Name) Text TextAlign Width
    colPropertyNumber Property #   60
    colCity City   80
    colState State Center 40
    colStories Stories Right 44
    colYearBuilt Year Built Right  
    colBedrooms Beds Right 40
    colBathrooms Baths Right 40
    colCondition Condition   70
     colStatus Status    
    colMarketValue Value Right  
  5. Click OK
  6. Press F5 to execute
  7. Close the form and return to your programming environment

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();

Using a List View

 

Selecting an Item

As mentioned previously, a list view is made of a list of items. An item can be identified by its index:

  • On a large image or a small image style, the item on the top-left side has an index of 0. The second item from the left has an index of 1, and so on, up to the subsequent lines, if any
  • On a list style, the top item on the left column has an index of 0. The second item from top on the left column has an index of 1, and so on, up to the subsequent columns, if any
  • On a details style, the most top item has an index of 0. The second item from the top has an index of 1, and so on 

When a list view comes up, it displays its list of items. To use an item, the user can click it. When an item has been clicked, the control fires a SelectedIndexChanged event. The SelectedIndexChanged event is of type EventArgs, which means it does not carry any significant information except to let you know that an item has been clicked. Worse, this event does not even let you know the index of the item that was clicked. This means that you must work on your own to identify the item that was clicked.

When the user clicks an item, you can use a technique to identify the item that was selected, when another item gets selected, the the item that was previously selected fires an ItemSelectionChanged event.

Editing a Label

Clicking an item once allows the user to select it. You may create an application that allows the user to edit an item, that is, to change the string that the item displays. To edit an item, the user can click (once) an item, then click (once) the item again. This puts it into edit mode. The user can then use the keyboard to change the string of the item:

To support the ability to let the user edit an item, the ListView class is equipped with the LabelEdit Boolean property. The default value of this property is false, which would prevent the user from editing the item in the list view. If you set this property to true, the user can click, then click the item to edit it.

When the user starts editing, the control fires a BeforeLabelEdit event. This event allows you to take care of some early processing, such as checking what the user is doing or canceling the editing.

If you allow the user to edit the item, after the user has edited it, the control fires an AfterLabelEdit event. 

Both the BeforeLabelEdit and the AfterLabelEdit events are of type LabelEditEventArgs. One of the pieces of information that this class provides is the index of the item that is being edited. This index is held by the Item property of the LabelEditEventArgs class. To get the string resulting from the user editing, the LabelEditEventArgs class is equipped with the Label property. When the control fires a BeforeLabelEdit or the a AfterLabelEdit event, to help you decide whether to accept or reject the change, the LabelEditEventArgs class is equipped with the CancelEdit Boolean property.

Activating an Item

When an item has been selected, it becomes highlighted. If you use the LabelEdit property to allow the user to edit an item, this is a local edition. In the next sections, we will learn how to add sub-items to a list view item. When an item is equipped with sub-items, you may want your application to allow the user to change the item, one of its sub-items, or everything. Before doing anything, an item must be activated. There are three ways an item has been activated.

The technique used to activate an item is supported by the Activation property. The Activation property is based on the ItemActivation enumeration that has three members:

  • Standard: When the Activation property is set to Standard, to activate an item, the user must double-click the item
  • OneClick: With this option, the user would click an item once to active it
  • TwoClick: If you set the Activation property to this member, the user would have to click the item, then click it again to activate it (clicking once and clicking again once is not the same as double-clicking)

When an item has been activated, the control fires an ItemActivate event. You can use either this or the SelectedIndexChanged event to process the item.

Using Columns

Besides the items, the user can also use the columns. For example, you can allow the user to re-arrange or sort the list of items with the user clicks a column. When the user a column header, the control fires a ColumnClick event. The ColumnClick event is of type ColumnClickEventArgs. The ColumnClickEventArgs class is equipped with the Column integer property that allows you to identify the index of the column that was clicked.

Besides clicking a column header, the user can also resize a column by dragging the line separator between two columns. If the user decides to resize a column and starts dragging the line separator, the control fires ColumnWidthChanging event. After the user has resized a column, the control fires a ColumnWidthChanged event.

Identifying an Item

The only actual property that the nested ListViewItemCollection class is equipped with is the default Item property. This property allows you to identify an item. There are two versions of the Item property. You can identify an item using its index, which is its zero-based position. As an alternative, you can identify an item using its string.

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:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WinForms1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            lvwCountries.View = View.Details;

            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 lviPortugal = new ListViewItem("Portugal");
            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);
        }
    }
}

This would produce:

Countries Statistics

Visually Creating Sub Items

To visually create the sub-items, you must use the ListViewSubItem Collection Editor. To get it, first access the Properties window of the list view and click the ellipsis button of the Items field. As mentioned previously, this would open the ListView Collection Editor. From that dialog box, you can click the ellipsis button of the SubItems field.

When the ListViewSubItem Collection Editor comes up, to create a sub-item of the current item, you can click Add. Then, on the right side, define the characteristics of the sub-items. You can continue this until you have created all necessary sub-items.

Application Application: Visually Creating Sub Items

  1. On the form, click the list view
  2. In the Properties window, click Items and click its ellipsis button
  3. In the ListView Collection Editor, as the first item is selected, on the right side, click SubItems and click its ellipsis button
  4. In the ListViewSubItem Collection Editor, click Add
  5. On the right side, click Text and type Silver Spring
  6. Click Add again
  7. On the right side, click Text and type MD
  8. Click Add again
  9. On the right side, click Text and type 3
  10. Click Add again
  11. On the right side, click Text and type 1996
     
  12. Click OK
  13. Click OK

Programmatically 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:

using System;
using System.Drawing;
using System.Windows.Forms;

public class Exercise : Form
{
    ListView lvwCountries;

    public Exercise()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        Text = "Countries Statistics";
        Size = new Size(452, 218);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 160; lvwCountries.View = View.Details;

        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);

        StartPosition = FormStartPosition.CenterScreen;
        Controls.Add(lvwCountries);
    }
}

public class Program
{
    static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

This would produce:

Countries Statistics

As mentioned above, each sub-item is of type ListViewSubItem. The ListViewSubItem class is equipped with three constructors. The default constructor 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:

using System;
using System.Drawing;
using System.Windows.Forms;

public class Exercise : System.Windows.Forms.Form
{
    ListView lvwCountries;

    public Exercise()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        Text = "Countries Statistics";
        Size = new Size(452, 150);

        lvwCountries = new ListView();
        lvwCountries.Location = new Point(12, 12);
        lvwCountries.Width = 420;
        lvwCountries.Height = 100;
        lvwCountries.View = View.Details;

        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);

        StartPosition = FormStartPosition.CenterScreen;
        Controls.Add(lvwCountries);
    }
}

public class Program
{
    static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

This would produce:

Countries Statistics

If you call the ListViewSubItemCollection.Add() method to create a sub-item, the new sub-item 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 ListViewSubItemCollection.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.

ApplicationApplication: Creating Sub-Items

 
  1. Open the form, double-click the New Property button and change the file as follows:
    private void ShowProperties()
    {
        // Get a reference to the file that holds the records of properties
        string Filename = @"C:\Altair Realtors\properties.atr";
    
        // Make sure the file exists
        if (File.Exists(Filename) == true)
        {
            // if so, create a file stream
            FileStream stmProperties = new FileStream(Filename,
                                                      FileMode.Open,
                                                      FileAccess.Read);
            // Create a binary formatter
            BinaryFormatter bfmProperty = new BinaryFormatter();
            // If some properties were created already,
            // get them and store them in the collection
            properties = 
            	(List<RealEstateProperty>)bfmProperty.Deserialize(stmProperties);
    
            // First, empty the list view
            lvwProperties.Items.Clear();
            ListViewItem lviProperty = null;
    
            // Visit each property in the collection and add it to the list view
            foreach (RealEstateProperty house in properties)
            {
                if (house.PropertyType.Equals("Condominium"))
                    lviProperty = new ListViewItem(house.PropertyNumber, 
                    		lvwProperties.Groups[0]);
                else if (house.PropertyType.Equals("Townhouse"))
                    lviProperty = new ListViewItem(house.PropertyNumber, 
                    		lvwProperties.Groups[1]);
                else // if (house.PropertyType.Equals("Single Family"))
                    lviProperty = new ListViewItem(house.PropertyNumber, 
                    		lvwProperties.Groups[2]);
    
                lviProperty.SubItems.Add(house.City);
                lviProperty.SubItems.Add(house.State);
                lviProperty.SubItems.Add(house.Stories.ToString());
                lviProperty.SubItems.Add(house.YearBuilt.ToString());
                lviProperty.SubItems.Add(house.Bedrooms.ToString());
                lviProperty.SubItems.Add(house.Bathrooms.ToString("F"));
                lviProperty.SubItems.Add(house.Condition);
                lviProperty.SubItems.Add(house.Status);
                lviProperty.SubItems.Add(house.MarketValue.ToString());
                lvwProperties.Items.Add(lviProperty);
            }
    
            // Close the file stream
            stmProperties.Close();
        }
    }
    
    private void btnNewProperty_Click(object sender, EventArgs e)
    {
        PropertyEditor editor = new PropertyEditor();
    
        Random rndNumber = new Random(DateTime.Now.Millisecond);
        int number1 = rndNumber.Next(100, 999);
        int number2 = rndNumber.Next(100, 999);
        string propNumber = number1 + "-" + number2;
    
        editor.txtPropertyNumber.Text = propNumber;
    
        // Check that the directory that contains the list of properties exists.
        // If it doesn't exist, create it
        DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Altair Realtors");
        // Get a reference to the file that holds the properties
        string Filename = @"C:\Altair Realtors\properties.atr";
    
        // First check if the file was previously created
        if (File.Exists(Filename) == true)
        {
            // If the list of properties exists already,
            // get it and store it in a file stream
            FileStream stmProperties = new FileStream(Filename,
                                                      FileMode.Open,
                                                      FileAccess.Read);
            BinaryFormatter bfmProperty = new BinaryFormatter();
            // Store the list of properties in the collection
            properties = (List<RealEstateProperty>)bfmProperty.Deserialize(stmProperties);
            // Close the file stream
            stmProperties.Close();
        }
    
        if( editor.ShowDialog() == DialogResult.OK )
        {
            ListViewItem lviStoreItem = 
            	new ListViewItem(editor.txtPropertyNumber.Text);
            RealEstateProperty prop = new RealEstateProperty();
    
            prop.PropertyNumber = editor.txtPropertyNumber.Text;
            prop.PropertyType   = editor.cbxPropertyTypes.Text;
            prop.City           = editor.txtCity.Text;
            prop.State          = editor.cbxStates.Text;
            prop.Stories        = short.Parse(editor.txtStories.Text);
            prop.YearBuilt      = int.Parse(editor.txtYearBuilt.Text);
            prop.Bedrooms       = short.Parse(editor.txtBedrooms.Text);
            prop.Bathrooms      = float.Parse(editor.txtBathrooms.Text);
            prop.Condition      = editor.cbxConditions.Text;
            prop.Status         = editor.cbxStatus.Text;
            prop.MarketValue    = double.Parse(editor.txtMarketValue.Text);
            if (!editor.pictureFile.Equals(""))
            {
                FileInfo flePicture = new FileInfo(editor.pictureFile);
                flePicture.CopyTo(@"C:\Altair Realtors\" +
                                  editor.txtPropertyNumber.Text + 
                                  flePicture.Extension);
                prop.PictureFile = @"C:\Altair Realtors\" +
                                  editor.txtPropertyNumber.Text + 
                                  flePicture.Extension;
            }
            else
                prop.PictureFile = @"C:\Altair Realtors\000-000.jpg";
            // Add the property in the collection
            properties.Add(prop);
    
            // Get a reference to the properties file
            string strFilename = dirInfo.FullName + "\\properties.atr";
            // Create a file stream to hold the list of properties
            FileStream stmProperties = new FileStream(strFilename,
                                                      FileMode.Create,
                                                      FileAccess.Write);
            BinaryFormatter bfmProperty = new BinaryFormatter();
    
            // Serialize the list of properties
            bfmProperty.Serialize(stmProperties, properties);
            // Close the file stream
            stmProperties.Close();
    
            // Show the list of properties
            ShowProperties();
        }
    }
  2. Return to the form
  3. Click the list view
  4. In the Properties window, click Events
  5. Double-click ItemSelectionChanged
  6. Implement the event as follows:
    private void lvwProperties_ItemSelectionChanged(object sender, 
    			ListViewItemSelectionChangedEventArgs e)
    {
        RealEstateProperty currentProperty = new RealEstateProperty();
    
        foreach (RealEstateProperty prop in properties)
        {
            if( prop.PropertyNumber.Equals(e.Item.SubItems[0].Text) )
                pbxPicture.Image = Image.FromFile(prop.PictureFile);
        }
    }
  7. In the Properties window, click the Properties button Properties

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:

  • Font: This allows you to apply a font of your choice for a particular sub-item. This would be done as follows:
     
    ListViewItem lviSweden = new ListViewItem("Sweden");
    lviSweden.UseItemStyleForSubItems = false;
    ListViewItem.ListViewSubItem subSweden = 
    	new ListViewItem.ListViewSubItem(lviSweden, "449,964");
    . . .
    subSweden = new ListViewItem.ListViewSubItem(lviSweden, "Stockholm");
    subSweden.Font = new Font("Times New Roman", 14, FontStyle.Italic);
    lviSweden.SubItems.Add(subSweden);
    . . .
    Countries Statistics
  • ForeColor: Instead writing a sub-item's text in black, you can assign the desired color to this property to use a different color. This would be done as follows:
     
    ListViewItem.ListViewSubItem subSweden = 
              new ListViewItem.ListViewSubItem(lviSweden, "449,964");
    subSweden.ForeColor = Color.Red;
    lviSweden.SubItems.Add(subSweden);
    Countries Statistics
  • BackColor: This property allows an individual sub-item to display on top of a specify color. This would be done as follows:
     
    subSweden = new ListViewItem.ListViewSubItem(lviSweden, "8,878,085");
    subSweden.BackColor = Color.Blue;
    lviSweden.SubItems.Add(subSweden);
    Countries Statistics

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 the 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:

  • Font: If you assign a new font to the item, this property allows you to apply a font of your choice to a particular sub-item. This would be done as follows:
     
    . . .
    ListViewItem lviAustralia = new ListViewItem("Australia");
    lviAustralia.Font = new Font("Georgia", 8, FontStyle.Bold);
    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);
    . . .
    Countries Statistics
  • ForeColor: You can assign the desired color to ListViewItem.ForeColor property to paint the item with a color of your choice. This would be done as follows:
     
    ListViewItem lviSweden = new ListViewItem("Sweden");
    lviSweden.ForeColor = Color.Red;
    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);
    Countries Statistics
  • BackColor: The ListViewItem.BackColor property allows you to paint the background of an item with a color of your choice. This would be done as follows:
     
    ListViewItem lviEgypt = lvwCountries.Items.Add("Egypt");
    lviEgypt.BackColor = Color.Blue;
    lviEgypt.SubItems.Add("1,001,450");
    lviEgypt.SubItems.Add("74,718,797");
    lviEgypt.SubItems.Add("Cairo");
    lviEgypt.SubItems.Add("eg");
    Countries Statistics

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.

 

ApplicationApplication: Deleting Items

  1. On the form, right-click the list view and create Edit Items...
  2. In the Members list, click the first item and click Remove
  3. Click the other item and click Remove
  4. Click OK

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;
    Countries Statistics
  • Nonclickable: The columns are flat and don't change their appearance when the user clicks one:
     
    lvwCountries.HeaderStyle = ColumnHeaderStyle.Nonclickable;
    Countries Statistics
  • None: No column header appears:
     
    lvwCountries.HeaderStyle = ColumnHeaderStyle.None;
    Countries Statistics

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.

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.

ApplicationApplication: Allowing Full Row Selection

  1. On the form, click the list view
  2. In the Properties window, double-click FullRowSelect property to set its value to True

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;
Countries Statistics
 

Application Application: Writing Code For a Toolbar

  1. In the Properties window, double-click GridLines to set its value to True
  2. To execute the application, press F5
  3. Click the New property... button
  4. Create the list of properties
     
    Property Type City State Stories Year Built Bedrooms Bathrooms Condition Market Value Status
    Single Family Rockville MD 2 1988 3 2.5 Excellent 465580 Available
    Single Family Silver Spring MD 3 2002 5 3.5 Excellent 675880 Sold
    Townhouse Arlington VA 4 1995 4 3.5 Good 550665 Available
    Condominium Washington DC 6 1984 1 1 Good 285775 Available
    Single Family McLean VA 3 1992 5 3.5 Excellent 785680 Available
    Condominium Rockville MD 8 2006 2 1 Excellent 316925 Available
    Townhouse Washington DC 2 1975 3 1.5 Good 385600 Sold
    Townhouse Baltimore MD 3 1982 3 1 Good 275970 Available
  5. Execute the application and create a few properties as follows (the computer will generate the properties numbers)
     
    Altair Realtors
    Altair Realtors
  6. Close the form and return to your programming environment

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:

lvwCountries.CheckBoxes = true;
Countries Statistics
     
 

Home Copyright © 2010-2014, FunctionX