Mike19
Mike19

Reputation: 95

How to count the SubItems in a ListView?

I have diffrent entries in a ListView. I would like to count the entries (starting from the second column). The output should be under the "Total" column (see figure below, framed in red) How can this be achieved? With this code I can only access the individual rows:

for (int j = 1; j < listView1.Items[1].SubItems.Count; j++)               
{
   string s = listView1.Items[1].SubItems[j].Text;                   
}


enter image description here

Many thanks for your help!

Upvotes: 0

Views: 1194

Answers (1)

RafalW
RafalW

Reputation: 126

Here's your solution

    //iterate through all rows                      
    for (int i = 0; i < listView1.Items.Count; i++)
    {
        //make sure that 5 subitems are present
        int missingSubitemsCount = 5 - listView1.Items[i].SubItems.Count;
        for (int j = 0; j < missingSubitemsCount; j++)
            listView1.Items[i].SubItems.Add(new ListViewItem.ListViewSubItem());

        int count = 0;

        //test columns 1-3
        for (int j = 1; j < listView1.Items[i].SubItems.Count - 1; j++)
        {
            //check if empty
            if (String.IsNullOrEmpty(listView1.Items[i].SubItems[j].Text) == false)
                count++;                    
        }                
            
        //update last column
        listView1.Items[i].SubItems[4].Text = count.ToString();
    }  

However, i think it would be better to use DataGridView and data binding instead. Operating directly on control can cause problems when project gets bigger. Its just better to separate data from view

Here's how i would do it with DataGridView

    class MyItem
    {
        public string Name { get; set; }
        public string Property1 { get; set; }
        public string Property2 { get; set; }
        public string Property3 { get; set; }
        public int Total { get; set; }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        var items = new List<MyItem>();

        items.Add(new MyItem
        {
            Name = "Books",
            Property1 = "A",
            Property2 = "B",
            Property3 = "C"
        });

        items.Add(new MyItem
        {
            Name = "Pencils",
            Property1 = "A",
            Property2 = "B",                
        });

        items.Add(new MyItem
        {
            Name = "Tapes",
            Property1 = "A",                
        });
       
        //iterate through all items
        foreach (var item in items)
        {
            //get list of MyItem properties starting with "Property"
            foreach (var property in typeof(MyItem).GetProperties().Where(u => u.Name.StartsWith("Property")))
            {
                //test if null or empty, increment Total if not
                if (property.GetValue(item) != null && String.IsNullOrEmpty(property.GetValue(item).ToString()) == false)
                    item.Total++;                    
            }

            //Alternative: Same calculation in one line
            item.Total = typeof(MyItem).GetProperties().Count(u => u.Name.StartsWith("Property") && u.GetValue(item) != null && String.IsNullOrEmpty(u.GetValue(item).ToString()) == false);
        }

        //bind items to DataGridView
        dataGridView1.DataSource = items;            
    }

Upvotes: 1

Related Questions