21 Jun

C# Sort Listview Items By Columns

The ListView control enables us to use sorting other than that provided by the Sorting property. When the ListView control sorts items, it uses a class that implements the System.Collections.IComparer interface. This class provides the sorting features used to sort each item. To use a custom item sorter, we create an instance of IComparer class and assign it to the ListViewItemSorter property of the ListView. Following sample shows us String and Datetime comparison for string and datetime columns in ListView control.

Sample project can be downloaded from following link:
ListViewSortColumnsExample.rar

Class examples that implements the System.Collections.IComparer interface:
Example 1:

    /// 
    /// Implements the manual sorting of items by column.
    /// 
    class ListViewItemStringComparer : IComparer
    {
        private int col;
        private SortOrder order;
        public ListViewItemStringComparer()
        {
            col = 0;
            order = SortOrder.Ascending;
        }

        public ListViewItemStringComparer(int column, SortOrder order)
        {
            col = column;
            this.order = order;
        }

        public int Compare(object x, object y) 
        {
            int returnVal= -1;
            returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
                                       ((ListViewItem)y).SubItems[col].Text);

            // Determine whether the sort order is descending.
            if (order == SortOrder.Descending)
                // Invert the value returned by String.Compare.
                returnVal *= -1;

            return returnVal;
        }
    }

Example 2:

    class ListViewItemDateTimeComparer : IComparer
    {
        private int col;
        private SortOrder order;
        public ListViewItemDateTimeComparer()
        {
            col = 0;
            order = SortOrder.Ascending;
        }

        public ListViewItemDateTimeComparer(int column, SortOrder order)
        {
            col = column;
            this.order = order;
        }
        
        public int Compare(object x, object y)
        {
            int returnVal;
            // Determine whether the type being compared is a date type.
            try
            {
                // Parse the two objects passed as a parameter as a DateTime.
                System.DateTime firstDate =
                        DateTime.Parse(((ListViewItem)x).SubItems[col].Text);
                System.DateTime secondDate =
                        DateTime.Parse(((ListViewItem)y).SubItems[col].Text);

                // Compare the two dates.
                returnVal = DateTime.Compare(firstDate, secondDate);
            }
            // If neither compared object has a valid date format, compare
            // as a string.
            catch
            {
                // Compare the two items as a string.
                returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
                                           ((ListViewItem)y).SubItems[col].Text);
            }

            // Determine whether the sort order is descending.
            if (order == SortOrder.Descending)
                // Invert the value returned by String.Compare.
                returnVal *= -1;

            return returnVal;
        }
    }