How to sort integers in a list

How to sort integer columns in a ListView

C #,. Net 2.0, Winform

System.Windows.Forms.ListView

+6
c # listview winforms
source share
7 answers

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.

+19
source share

If you start with ListView, your life will be much easier if you use ObjectListView instead . ObjectListView is an open source .NET WinForms ListView wrapper, and it solves all these nasty problems that usually make ListView so frustrating. For example, it automatically sorts int, so that "100" appears after "3" (DateTimes, bools and everything else also sorts correctly).

Seriously, you'll never want to return to a simple ListView after using an ObjectListView.

Yes, I’m the author, but that doesn’t mean that I am biased ... Well, maybe this is it :) Look here for some other people.

+5
source share

You will need to create a class that implements the IComparer interface (not generic). In this class, you read the Text property from the correct subitem, convert it to int, and perform a comparison:

 public class IntegerComparer : IComparer { private int _colIndex; public IntegerComparer(int colIndex) { _colIndex = colIndex; } public int Compare(object x, object y) { int nx = int.Parse((x as ListViewItem).SubItems[_colIndex].Text); int ny = int.Parse((y as ListViewItem).SubItems[_colIndex].Text); return nx.CompareTo(ny); } } 

Then you assign such a comparison with the ListViewItemSorter property and call the ListView control's sort method:

 // create a comparer for column index 1 and assign it to the control, and sort myListView.ListViewItemSorter = new IntegerComparer(1); myListView.Sort(); 
+3
source share

I would do this in a data source (model) instead of a view. Sort it there, and it should update it in the view via data binding.

0
source share

I used the Neil-N class, but modified the if statement to check the Type property instead of the Tag property. I set each column to Type Number (instead of Text) in which there was an integer value. Sorting works great.

 if (l1.ListView.Columns[Column].Type.ToString() == "Number") 
0
source share
 class ListViewAutoSorter : System.Collections.IComparer { private int Column = 0; private System.Windows.Forms.SortOrder Order = SortOrder.Ascending; public ListViewAutoSorter(int Column, SortOrder Order) { this.Column = Column; this.Order = Order; } public int Compare(object x, object y) // IComparer Member { if (!(x is ListViewItem)) return (0); if (!(y is ListViewItem)) return (0); var l1 = (ListViewItem)x; var l2 = (ListViewItem)y; var value1 = 0.0; var value2 = 0.0; if (Double.TryParse(l1.SubItems[Column].Text, out value1) && Double.TryParse(l2.SubItems[Column].Text, out value2)) { if (Order == SortOrder.Ascending) { return value1.CompareTo(value2); } else { return value2.CompareTo(value1); } } else { var str1 = l1.SubItems[Column].Text; var str2 = l2.SubItems[Column].Text; if (Order == SortOrder.Ascending) { return str1.CompareTo(str2); } else { return str2.CompareTo(str1); } } } } 
0
source share
 Public Class Form1 Private Sub btnSortListView_Click(sender As Object, e As EventArgs) Handles btnSortListView.Click If btnSortListView.Text = "Sort Ascending" Then ListViewGar.ListViewItemSorter = New IntegerComparer(1) ListViewGar.Sort() btnSortListView.Text = "Not Sort" Else ListViewGar.ListViewItemSorter = New IntegerComparer(0) btnSortListView.Text = "Sort Ascending" End If End Sub End Class Public Class IntegerComparer Implements System.Collections.IComparer Private _colIndex As Integer Public Sub New(ByVal colIndex As Integer) MyBase.New Me._colIndex = colIndex End Sub 'Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer ' Dim nx As Integer = Integer.Parse(CType(x, ListViewItem).SubItems(Me._colIndex).Text) ' Dim ny As Integer = Integer.Parse(CType(y, ListViewItem).SubItems(Me._colIndex).Text) ' Return nx.CompareTo(ny) 'End Function Private Function IComparer_Compare(x As Object, y As Object) As Integer Implements IComparer.Compare Dim nx As Integer = Integer.Parse(CType(x, ListViewItem).SubItems(Me._colIndex).Text) Dim ny As Integer = Integer.Parse(CType(y,ListViewItem).SubItems(Me._colIndex).Text) Dim colIndPlus As Integer = Me._colIndex Do While nx.CompareTo(ny) = 0 colIndPlus = colIndPlus + 1 nx = Integer.Parse(CType(x, ListViewItem).SubItems(colIndPlus).Text) ny = Integer.Parse(CType(y, ListViewItem).SubItems(colIndPlus).Text) Loop Return nx.CompareTo(ny) End Function End Class 

image before and after sorting

0
source share

All Articles