Shiridish
Shiridish

Reputation: 4962

Listview is not sorting properly in c#

I am trying to sort a listview and then remove redundant items. But neither the items are sorted properly nor the redundancies are removed completely. Please help..

lvwMessages.Sorting = SortOrder.Descending; 

for (int i = 0; i < lvwMessages.Items.Count - 1; i++)
{
   if (lvwMessages.Items[i].Tag == lvwMessages.Items[i + 1].Tag)
       lvwMessages.Items[i + 1].Remove();    
}

Listview at runtime with unsorted and redundant items

Upvotes: 0

Views: 795

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

Property Sorting sorts items based on the item text. If you want to sort the items in the ListView based on Tag, you should use the Sort method. The Sort method uses the IComparer specified in the ListViewItemSorter property to perform a manual sort of the items in the ListView.

Here is an example of sorter:

public class ListViewItemComparer : IComparer
{
    public int Compare(object x, object y)
    {
        YourType a = (YourType)((ListViewItem)x).Tag;
        YourType b = (YourType)((ListViewItem)y).Tag;
        // compare tags
        return a.CompareTo(b);
    }
}

Usage:

listView.ListViewItemSorter = new ListViewItemComparer();

If you want to change sorting direction, multiply result by -1 or use b.Compare(a).

Upvotes: 0

SWeko
SWeko

Reputation: 30872

You are changing the collection as you are iterating it. That always has some funny side-effects.

E.G. Let's say you have five items with ids and tags, respectively,

ID0 - Tag1 
ID1 - Tag1 
ID2 - Tag1
ID3 - Tag2
ID4 - Tag2.

First time through the loop, i = 0, and the Items collection has 5 elements. ID0 is compared with ID1, and ID1 is removed.

Next time through the loop, i=1, and the Items collection has 4 elements. Now, instead of comparing ID0 with ID2, ID2 is compared with ID3, and nothing is removed, etc...

You could use something like this:

int i = 0;
while (i < lvwMessages.Items.Count - 1)
{
   if (lvwMessages.Items[i].Tag == lvwMessages.Items[i + 1].Tag)
      lvwMessages.Items[i + 1].Remove();    
   else
      i++;
}

incrementing the counter only if you have not removed an item.

Upvotes: 2

Related Questions