0

I have 3 columns in my ListView: name, string value and int value.

Name:Item1, Item2, Item3

string value:A, B, A

int value:3,2,1

I want to sort my ListView first, by string value. Like this:

Name:Item1, Item3, Item2

string value:A, A, B

int value:3,1,2

After that I want to sort by int value. Like this:

Name:Item3, Item1, Item2

string value:A, A, B

int value:1,3,2

To do this should I use List<> or is there any way?
If I should use List<> what is the proper way to the it?

Jimi
  • 29,621
  • 8
  • 43
  • 61
piston2033
  • 15
  • 8

3 Answers3

3

You can use a custom ListViewItemSorter to sort the columns of a ListView control.

This is an custom overloaded IComparer that lets you specify 1 or 2 columns for sorting, with the option to pass no parameters for a default Column[0] order.

Specify a sort order:

listView1.Sorting = SortOrder.Ascending;

...and the Indexes of the Columns you want to compare. The order in which you enter them is of course important. In you example you should enter:

listView1.ListViewItemSorter = new ListViewItemComparer(1, 2);

The Default sorting Column[0] can be set like this:

listView1.ListViewItemSorter = new ListViewItemComparer();

The ListViewItemComparer Class:

class ListViewItemComparer : IComparer
{
    private int col1 = -1;
    private int col2 = -1;

    public ListViewItemComparer() => col1 = 0;
    public ListViewItemComparer(int Column) => col1 = Column;

    public ListViewItemComparer(int Column1, int Column2)
    {
        col1 = Column1;
        col2 = Column2;
    }

    public int Compare(object x, object y)
    {
        int result = string.Compare(((ListViewItem)x).SubItems[col1].Text, 
           ((ListViewItem)y).SubItems[col1].Text);
        if (!(col2 < 0))
            result |= string.Compare(((ListViewItem)x).SubItems[col2].Text, 
           ((ListViewItem)y).SubItems[col2].Text);
        return result;
    }
}
Jimi
  • 29,621
  • 8
  • 43
  • 61
1

Assuming IEnumerable<T> like a List<T>

List<T> sortedList = list.OrderBy(x => x.Col1).ThenBy(x => x.Col2).ThenBy(x => x.Col3).ToList();
Zer0
  • 7,191
  • 1
  • 20
  • 34
1

Use LINQ OrderBy and ThenBy to sort the letter(string) and number (int) properties:

List<myClass> myList = new List<myClass>()
{
    new myClass(){name="Item1",letter="A", number=3 },
    new myClass(){name="Item2",letter="B", number=2 },
    new myClass(){name="Item3",letter="A", number=1 }
};

var result = myList.OrderBy(x => x.letter).ThenBy(x => x.number).ToList();

result:

name:Item3, Item1, Item2

letter:A, A, B

number:1,3,2

Add items from the list result to ListView:

listView1.View = View.Details;
listView1.Columns.Add("name");
listView1.Columns.Add("letter");
listView1.Columns.Add("number");
foreach (var item in result)
{
    listView1.Items.Add(new ListViewItem(new string[] { item.name,item.letter,item.number.ToString()}));
}

myClass:

class myClass
{
    public string name { get; set; }
    public string letter { get; set; }
    public int number { get; set; }
}

DEMO HERE

Slaven Tojić
  • 2,945
  • 2
  • 14
  • 33
  • Probably I will use this method, but a question. What do you suggest? Using this or @Jimi 's method. This seems easy but I have no idea about performance. – piston2033 May 05 '18 at 03:30
  • 1
    The answers on this question :[LINQ_orderby_vs_IComparer](https://stackoverflow.com/questions/3378603/linq-orderby-vs-icomparer) suggest to use my solution (LINQ OrderBy). – Slaven Tojić May 06 '18 at 05:09