This is how I was able to sort by multiple columns and the ability to sort each column as a number or as text.
First use this class:
class Sorter : System.Collections.IComparer { public int Column = 0; public System.Windows.Forms.SortOrder Order = SortOrder.Ascending; public int Compare(object x, object y) // IComparer Member { if (!(x is ListViewItem)) return (0); if (!(y is ListViewItem)) return (0); ListViewItem l1 = (ListViewItem)x; ListViewItem l2 = (ListViewItem)y; if (l1.ListView.Columns[Column].Tag == null) { l1.ListView.Columns[Column].Tag = "Text"; } if (l1.ListView.Columns[Column].Tag.ToString() == "Numeric") { float fl1 = float.Parse(l1.SubItems[Column].Text); float fl2 = float.Parse(l2.SubItems[Column].Text); if (Order == SortOrder.Ascending) { return fl1.CompareTo(fl2); } else { return fl2.CompareTo(fl1); } } else { string str1 = l1.SubItems[Column].Text; string str2 = l2.SubItems[Column].Text; if (Order == SortOrder.Ascending) { return str1.CompareTo(str2); } else { return str2.CompareTo(str1); } } } }
In the form constructor, set the sorter as follows:
lvSeries.ListViewItemSorter = new Sorter();
Then handle the ColumnClick of even your listview control as follows:
private void lvSeries_ColumnClick(object sender, ColumnClickEventArgs e) { Sorter s = (Sorter)lvSeries.ListViewItemSorter; s.Column = e.Column; if (s.Order == System.Windows.Forms.SortOrder.Ascending) { s.Order = System.Windows.Forms.SortOrder.Descending; } else { s.Order = System.Windows.Forms.SortOrder.Ascending; } lvSeries.Sort(); }
It all depends on the Tag property for each column, which is either set to "Numeric" or not, so the sorter knows how to sort.
In the above example, I pass the values as a float, when numeric, you can change it to int.
Neil n
source share