Dumbo
Dumbo

Reputation: 14142

selecting Multiple row of items in a ListView

I have a treeview which is in detail view. listview is populated with items and subitems which are in pair of 4 rows are related together. I have set Name property of each of rows in this 4 items the same.

What I am looking for, is when user selects a row, all the 4 rows which have similar Name propety be selected (hilighted) automatically.

What I have done so far is in below, but it does not compile!

private void resultSheet_SelectedIndexChanged(object sender, EventArgs e)
{
    string name = resultSheet.SelectedItems[0].Name.ToString();

    ListView.ListViewItemCollection items = new ListView.ListViewItemCollection(resultSheet);

    foreach (ListViewItem item in resultSheet.Items)
    {
        if (item.Name.ToString() == name) 
        {
            items.Add(item);
        }
    }

    resultSheet.SelectedItems = items; //Does not compile 

}

Upvotes: 0

Views: 15092

Answers (2)

Tim Schmelter
Tim Schmelter

Reputation: 460278

ListView.SelectedItems is readonly.

if(resultSheet.SelectedItems.Count >= 1)
{
    string name = resultSheet.SelectedItems[0].Name.ToString();
    foreach (ListViewItem item in resultSheet.Items)
    {
        item.Selected = item.Name.ToString() == name; 
    }
}

Edit: Acccording to your comment on the other answer: Make sure that SelectedItems.Count >= 1 before accessing the item at index 0, because "No selection" is also a possible state. When you select another item, the ListView unselects the SelectedItem before selecting the new item

If you want to avoid unnecessary SelectedIndexChanged events, try Robert's Timer-ListView approach or this Application.Idle approach(VB.NET but easy to convert) what is used by ObjectListView under the hood to prevent from multiple events triggering.

Upvotes: 2

Fischermaen
Fischermaen

Reputation: 12468

Just change your method in this way:

 bool inAction = false;

 private void resultSheet_SelectedIndexChanged(object sender, EventArgs e)
 {
     if (inAction || (resultSheet.SelectedItems.Count == 0))
     {
         return;
     }
     inAction = true;
     string name = resultSheet.SelectedItems[0].Name;

     foreach (ListViewItem item in resultSheet.Items)
     {
         if (item.Name.ToString() == name)
         {
             item.Selected = true;
         }
     }
     inAction = false;
 } 

Edit: Or if you prefer LINQ, do it like this:

 bool inAction = false;

 private void resultSheet_SelectedIndexChanged(object sender, EventArgs e)
 {
     if (inAction || (resultSheet.SelectedItems.Count == 0))
     {
         return;
     }
     inAction = true;
     string name = resultSheet.SelectedItems[0].Name;

     foreach (ListViewItem item in resultSheet.Items.OfType<ListViewItem>().Where(item => item.Name == name))
     {
         item.Selected = true;
     }
     inAction = false;
 } 

Upvotes: 1

Related Questions