Wednesday, March 28, 2012

WinForms and C#: How to sort a ListView by column

Problem

How to sort a "WinForms.ListView" content when one of the columns are clicked

Solution

I don't remember where I found this great Sorter-class but just copy-paste it to your project as a new ListViewSorter class
public class ListViewSorter : System.Collections.IComparer
{
        public int Compare(object x, object y)
        {
            int result = 0;

            if (!(x is ListViewItem))
            {
                return result;
            }
            if (!(y is ListViewItem))
            {
                return result;
            }

            // Determine whether the type being compared is a date type.
            try
            {
                System.DateTime firstDate = DateTime.Parse(((ListViewItem)x).SubItems[ByColumn].Text);
                System.DateTime secondDate = DateTime.Parse(((ListViewItem)y).SubItems[ByColumn].Text);
                result = DateTime.Compare(firstDate, secondDate);
            }
            catch
            {        
                // Compare the two items as a string. 
                result = String.Compare(((ListViewItem)x).SubItems[ByColumn].Text, ((ListViewItem)y).SubItems[ByColumn].Text);
            }

            // Determine whether the sort order is descending. 
            if (((ListViewItem)x).ListView.Sorting == SortOrder.Descending)
            {
                // Invert the value returned by compare. 
                result *= -1;
            }

            LastSort = ByColumn;
            return result;
        }

        public int ByColumn
        {
            get { return Column; }
            set { Column = value; }
        }
        int Column = 0;

        public int LastSort
        {
            get { return LastColumn; }
            set { LastColumn = value; }
        }
        int LastColumn = 0;
}

After your class is ready you must declare a sorter object in the form:
private ListViewSorter listSorter = new ListViewSorter();

and create a new event for ListView ColumnClick to handle sorting
private void listMyList_ColumnClick(object sender, ColumnClickEventArgs e)
{
        listMyList.ListViewItemSorter = listSorter;
        if (listSorter.LastSort == e.Column)
        {
            // Change sort order for current column
            if (listMyList.Sorting == SortOrder.Ascending)
            {
                listMyList.Sorting = SortOrder.Descending;
            }
            else
            {
                listMyList.Sorting = SortOrder.Ascending;
            }
        }
        else
        {
            listMyList.Sorting = SortOrder.Descending;
        }
        listSorter.ByColumn = e.Column;
        listMyList.Sort();
}

No comments:

Post a Comment