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

ListView Sorter

Rate me:
Please Sign up or sign in to vote.
2.24/5 (16 votes)
22 May 2003 169.6K   1.4K   32   19
Custom ListViewItemSorter with pluggable cell comparators

Introduction

My solution is an alternative to C# Sorted ListView, posted by Carlos H.Perez. The main difference is that I'm not trying to extend ListView control at all. Instead of that I suggest using a standard ListView with customizable ListViewSorter.

The main idea is to tie ListView column headers with appropriate delegates, which can handle column cells comparison activities. So I declare ListViewSorter.Comparer delegate, and enable to store column-delegate pairs into sorter.

C#
//column cell comparer
public delegate int Comparer(string x, string y);
//comparer for column
public Comparer this[ColumnHeader _column] {...}

The sorter itself is tied to a list control and handles the ColumnClick events for that list. On each column the click sorter activates the clicked column.

C#
//click handler
protected void Column_Click(object sender, ColumnClickEventArgs e)
{
    //get and verify clicked list
    ListView _list = sender as ListView;
    if (_list != this.list) 
       throw new Exception("The event sender does not match the list");

    //sweap columns, which are no longer contained by the list
    CleanUp();

    //get clicked column header
    ColumnHeader _column = this.list.Columns[e.Column];

    //activate sort by that header
    SortBy(_column, this.column ! =_column || 
                    this.list.Sorting!=SortOrder.Ascending);
}

That active column later is used by sorting logic to choose correct comparer and to compare cells.

C#
//activates sort by column
public void SortBy(ColumnHeader _column, bool asc)
{
    //validate column
    if (this.list == null) throw new Exception("The list is null");
    if (_column == null) throw new Exception("The column is null");

    //leav old sort if column is not sortable
    if (this[_column] == null) return;

    //activate column
    this.column = _column;

    //activate sort
    this.list.Sorting = SortOrder.None;
    this.list.Sorting = asc ? SortOrder.Ascending : SortOrder.Descending;
}

Bellow is cell comparison through the Comparer implementation.

C#
//cell comparison
int IComparer.Compare(object x, object y)
{
    //validate list
    if (this.list == null || this.list.Sorting == SortOrder.None 
      || this.column == null) return 0;

    //get cells
    ListViewItem ix = x as ListViewItem;
    ListViewItem iy = y as ListViewItem;
    if (ix.ListView != this.list || iy.ListView != this.list)
        throw new Exception("The event sender does not match the list");

    //compare - use column comparer
    return
        (this.list.Sorting==SortOrder.Ascending ? 1:-1) *
        this[this.column](ix.SubItems[this.column.Index].Text, 
                          iy.SubItems[this.column.Index].Text);
}

ListViewSorter already has standard comparers (as static methods) for strings, numbers, dates.

History

  • 23 May 2003 - updated download

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
gz
Lithuania Lithuania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
NewsBug and fix Pin
Daniel Hilgarth25-Apr-06 3:00
Daniel Hilgarth25-Apr-06 3:00 
GeneralRe: Bug and fix Pin
M Sait Ozen13-Jul-06 11:27
M Sait Ozen13-Jul-06 11:27 
GeneralRe: Bug and fix Pin
Scott S.7-Aug-07 10:36
Scott S.7-Aug-07 10:36 
GeneralSimilar Approach, But With An Example Pin
FOOS29-Mar-05 12:08
FOOS29-Mar-05 12:08 
GeneralProblem with sorting Pin
robdogg13-May-04 8:25
robdogg13-May-04 8:25 
GeneralFrom MSDN Pin
mgvinod12-Jun-03 23:28
mgvinod12-Jun-03 23:28 
GeneralSorting CheckBoxes Pin
theoutlander3-Jun-03 11:14
theoutlander3-Jun-03 11:14 
GeneralListViewSorter Pin
Russell Mangel2-Jan-03 22:35
Russell Mangel2-Jan-03 22:35 
GeneralRe: ListViewSorter Pin
demerson14-Mar-05 13:38
demerson14-Mar-05 13:38 
GeneralRe: ListViewSorter Pin
kwirq8-May-06 10:45
kwirq8-May-06 10:45 
QuestionListView sorting Mutex? Pin
Tim M Miller2-Oct-02 1:43
Tim M Miller2-Oct-02 1:43 
AnswerRe: ListView sorting Mutex? Pin
Russell Mangel2-Jan-03 22:38
Russell Mangel2-Jan-03 22:38 
GeneralRe: ListView sorting Mutex? Pin
Tim M Miller7-Jan-03 2:57
Tim M Miller7-Jan-03 2:57 
GeneralRe: ListView sorting Mutex? Pin
Anonymous11-Jan-03 3:39
Anonymous11-Jan-03 3:39 
GeneralRe: ListView sorting Mutex? Pin
Tim M Miller22-Jan-03 1:22
Tim M Miller22-Jan-03 1:22 
Hi Russel,

You are absolutely right that populating a listview control can take longer with a ListViewSorter. From what I can see, this is not because it adds a real overhead, but because the ListViewSorter forces the ListView to redraw itself every time that an entry is added. Without the ListViewSorter, the ListView only seems to redraw itself while adding "visible" entries and not for entries outside the visible window. In other words when the scroll bar appears and items are appended to the end of the list, populating is lightening fast because no redraw occurs.

I haven't got to the root of the problem yet, but to get around it I do a listView.Hide() when populating a large list and then a listView.Show() after I have finished. I am showing a ProgressBar superimposed on the grayed out list and this updates very rapidly with each item. This is ok. for my application because once I have populated the list with around 1000 items, I am only interested in changing the existing items. Remember that the parent form needs to be visible in order for the ListView to update correctly when it is not visible. So it's parent.Show() and list.Hide().

If you are continually adding a large amount of items then you probably want to keep the ListView visible. I am not sure what to do about this at the moment, apart from saying that appending at the end of list (out of sight) will be a lot quicker than inserting at the beginning.

I hope this helps. Keep me posted if you find a way out!

Tim
GeneralRe: ListView sorting Mutex? Pin
ChristianD20-Jan-03 8:20
ChristianD20-Jan-03 8:20 
GeneralRe: ListView sorting Mutex? Pin
Tim M Miller22-Jan-03 1:35
Tim M Miller22-Jan-03 1:35 
GeneralRe: ListView sorting Mutex? Pin
ChristianD22-Jan-03 6:15
ChristianD22-Jan-03 6:15 
GeneralRe: ListView sorting Mutex? Pin
demerson15-Mar-05 8:09
demerson15-Mar-05 8:09 

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.