Click here to Skip to main content
15,890,825 members
Articles / Programming Languages / C#
Article

ListViewSortManager control

Rate me:
Please Sign up or sign in to vote.
4.89/5 (67 votes)
12 Dec 2004CPOL3 min read 376.4K   2K   97   147
Add column sorting to the ListView control the easy way.

Introduction

.NET's ListView control is a nice wrapper around the native List control, but the support for column sorting falls a bit short of what's commonly necessary. Some solutions to this problem require you to derive from a class that implements column sorting however. Since inheritance introduces very tight coupling between components, it is not the appropriate solution in every case. For example, your custom ListView derives from a class that implements functionality that you need except for column sorting and you cannot change the base class.

ListViewSortManager provides several useful features:

  • Easy to use.
  • Case-sensitive (ListViewTextSort) and case-insensitive (ListViewTextCaseInsensitiveSort) text sorting.
  • Integer (ListViewInt32Sort and ListViewInt64Sort) and floating-point (ListViewDoubleSort) sorting.
  • Date (ListViewDateSort) sorting.
  • Extendable for other specialized user-provided sort orders.
  • Transparently handles null and empty strings.
  • Transparently handles ascending and descending orderings.
  • Displays the sort order image in the column headers.
  • The user can specify the column and sort order at any time.
  • Automatic sorting can be disabled for batch insertion of elements to the list.

Usage

  1. Add a variable of type ListViewSortManager.
    C#
    private ListViewSortManager m_sortMgr;
  2. In your form's constructor, after the call to InitializeComponent(), construct the ListViewSortManager passing the list and an array of Type for sorters. There should be one entry in the array for each column in your list. The constructor takes care of hooking into the ListView's ColumnClick event.
    C#
    public MainForm()
    {
       //
       // Required for Windows Form Designer support
       //
       InitializeComponent();
    
       m_sortMgr = new ListViewSortManager(m_list, 
          new Type[] {
             typeof(ListViewTextSort),
             typeof(ListViewTextCaseInsensitiveSort),
             typeof(ListViewIntegerSort),
             typeof(ListViewFloatSort),
             typeof(ListViewDateSort)
          }
       );
    }
  3. Voilá! Column sorting has been added to your list.

Extended Usage

If you need to provide a sort ordering that doesn't match the ones provided, you just have to derive a class from ListViewTextSort and, override the OnCompare() method which receives two strings that have to be converted to whatever format that your comparison is based on.

C#
public class ListViewDateSort: ListViewTextSort
{
    public ListViewDateSort(int column, bool ascending):
        base(column, ascending)
    {
    }

    protected override int OnCompare(string lhs, string rhs)
    {
        return DateTime.Parse(lhs).CompareTo(DateTime.Parse(rhs));
    }
}

To Do

  • Investigate alternative, more efficient solutions for sorting that don't require text conversions. Probably, using ListView.Tag and adding overridables to ListViewSortManager.
  • As soon as C# implements generics, implement the comparers as templates.

Updates

Version 1.4 (12/11/04)

  • Added the SortEnabled property to enable/disable automatic sorting of the list's elements. Setting SortEnabled to false before adding a large number of elements to the list will speed up the insertion considerably. (Thanks to Jimmy S. for the suggestion.)
  • Added support for native header sort arrows when using version 6 of the Common Controls library. (Thanks to Arlen Feldman for the suggestion.)

Version 1.3 (02/17/03)

  • ShowHeaderIcon() always left-aligned the column header text regardless of the settings. (Thanks to Jezbo for spotting this).
  • ShowHeaderIcon() now locates the sorting arrow icon on the opposite side of the column header text.

Version 1.2 (11/08/02)

  • The ListViewSortManager's constructor now hooks up to the ColumnClick event making it much easier to use the control. (Thanks to debaser for the suggestion).
  • I forgot to set the transparency for the arrow images. (Thanks to Carlo J. Bos and Cory Smith for spotting this).
  • Made Sort() public again and added an overload that allows to select the column and sort order used. Also added Column and SortOrder properties (Thanks to Cory Smith for the suggestion).

Version 1.1 (11/07/02)

  • Implemented ascending/descending arrow images in column headers. No code changes are necessary to benefit from this.

Version 1.0 (04/22/02)

  • Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralFound a solution :-) Pin
Rommel the iCeMAn18-Nov-04 8:56
Rommel the iCeMAn18-Nov-04 8:56 
Generalswitch sorting off Pin
Jimmy S.2-Aug-04 22:37
Jimmy S.2-Aug-04 22:37 
GeneralRe: switch sorting off Pin
Jimmy S.3-Aug-04 0:30
Jimmy S.3-Aug-04 0:30 
GeneralRe: switch sorting off Pin
Epon13-Sep-04 22:07
Epon13-Sep-04 22:07 
GeneralRe: switch sorting off Pin
Jimmy S.14-Sep-04 20:51
Jimmy S.14-Sep-04 20:51 
GeneralRe: switch sorting off Pin
Luis Alonso Ramos20-Apr-05 14:35
Luis Alonso Ramos20-Apr-05 14:35 
GeneralVB Version Pin
Ferbz2-Aug-04 11:03
Ferbz2-Aug-04 11:03 
QuestionHave you considered using the HDF_SORTUP and HDF_SORTDOWN flags? Pin
ArlenFeldman10-Jul-04 15:28
ArlenFeldman10-Jul-04 15:28 
Have you considered using the HDF_SORTUP and HDF_SORTDOWN flags for the arrow on your header? This gives you Explorer-style up/down arrows without having to worry about image-lists, etc.

It is available with ComCtl 6 or later - which is pretty much everyone (although I admit that in my implementation I check the version and regress to images if prior to 6 - using your approach for drawing the bitmaps).



Arlen (www.cowthulu.com)
GeneralBrilliant! Pin
dzCepheus28-May-04 23:37
dzCepheus28-May-04 23:37 
Generalvb version Pin
auxcom25-May-04 15:48
auxcom25-May-04 15:48 
GeneralRe: vb version Pin
Eddie Velasquez26-May-04 5:52
Eddie Velasquez26-May-04 5:52 
GeneralRe: vb version Pin
Stevie17-Jun-04 4:24
Stevie17-Jun-04 4:24 
GeneralRe: vb version Pin
auxcom20-Jun-04 0:53
auxcom20-Jun-04 0:53 
GeneralSorting ListView when program loads Pin
Hal Director14-May-04 12:45
Hal Director14-May-04 12:45 
GeneralRe: Sorting ListView when program loads Pin
Eddie Velasquez15-May-04 8:07
Eddie Velasquez15-May-04 8:07 
GeneralRe: Sorting ListView when program loads Pin
Hal Director15-May-04 18:41
Hal Director15-May-04 18:41 
GeneralRe: Sorting ListView when program loads Pin
Eddie Velasquez17-May-04 0:42
Eddie Velasquez17-May-04 0:42 
GeneralRe: Sorting ListView when program loads Pin
Hal Director17-May-04 4:58
Hal Director17-May-04 4:58 
GeneralRe: Sorting ListView when program loads Pin
Eddie Velasquez17-May-04 8:18
Eddie Velasquez17-May-04 8:18 
GeneralUsing more listview.. Pin
roberto[ITA]28-Apr-04 3:56
roberto[ITA]28-Apr-04 3:56 
GeneralRe: Using more listview.. Pin
Eddie Velasquez28-Apr-04 14:47
Eddie Velasquez28-Apr-04 14:47 
GeneralSorting Integer Columns Pin
gruntledgoat19-Apr-04 4:51
gruntledgoat19-Apr-04 4:51 
GeneralRe: Sorting Integer Columns Pin
Eddie Velasquez19-Apr-04 8:58
Eddie Velasquez19-Apr-04 8:58 
GeneralRe: Sorting Integer Columns Pin
gruntledgoat19-Apr-04 9:41
gruntledgoat19-Apr-04 9:41 
GeneralRe: Sorting Integer Columns Pin
gruntledgoat29-Apr-04 7:24
gruntledgoat29-Apr-04 7:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.