A much faster sorting for ListView in WPF

In my first part of performance tuning techniques, I’ve reviewed some general approaches. Now I want to show you how to fine tune your ListView for sorting and displaying HUGE amount of rows. In this demo, I will show you that by using a custom sorter and virtualizingstackpanel, your sorting speed is about 100 times faster!

VirtualizingStackPanel.IsVirtualizing=”True”

First you need to specify the above property to true in your ListView, (this is the default value for ListView in WPF).

Then next, you need to use custom sorter, instead of SortDescriptions as described in my earlier blog. The key is using the CustomSort property of ListCollectionView:
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(myListView.ItemsSource);

Then in your ColumnHeader click event handler, you add something like the following:

view.CustomSort = sorter;
myListView.Items.Refresh();

Where sorter is a custom class you implement the IComparer interface.

Here is the demo of this custom (much faster!) sort program to sort 200,000 rows in a virtualized ListView in WPF:

In the demo, you see the custom sort takes about only 1.6 – 2 seconds to sort. I tried this 200,000 rows with SortDescriptions, and it takes about 3 minutes (~ 167 – 180 seconds) to sort this many rows. This is tested on both the .Net Framework 3.0 and the just released .Net Framework 3.5 Beta 2. Now you can enjoy a much more scalable ListView in WPF.๐Ÿ™‚

[Update 8/1/2007]

I’ve uploaded the project source code to demonstrate this sorting technique. You can get it here. You’ll need Visual Studio 2008 Beta 2 to open the solution file (or project file).

[Update 8/3/2007]

A modified version of the sample to support sorting multiple columns is posted here.ย  You’ll need Visual Studio 2008 Beta 2 to open the solution file (or project file).

[Updated: 1/16/2009]

The new source code link is updated at:

new source code link

28 Responses to A much faster sorting for ListView in WPF

  1. Josh Smith says:

    Nice work! Are you going to make a demo project available to download for us lazy people? ๐Ÿ™‚

    Thanks,
    Josh Smith

  2. ligao101 says:

    Thanks. I will probably make a demo for download later today๐Ÿ™‚

  3. ligao101 says:

    The demo project is uploaded to http://www.box.net/shared/2257apvyel

  4. JMan says:

    Great sample!

    But one drawback of this approach seems to be that you can only do single coulmn sort while using SortDescriptions allows you to do multicolumn sort. Or am I missing something…..?

  5. ligao101 says:

    To support multiple column sorting is easy. You can just modify the ListViewCustomComparer to use collections instead of single string to hold the sort column collections and in the ItemClass comparer class, in the Compare method, you then do additional compare if the previous column compare returns identical ( compare=0) result.

    I’ve posted the modified sample here at: http://www.box.net/shared/izogdded1q
    You can see how the multiple column sort is implemented.

  6. […] the meantime, Li Gao has what looks to be an excellent post on faster sorting for listviews in […]

  7. Dmitry says:

    Quick sort is good.
    What to do if I want only refresh sorted data after some binded property changed?
    Calling only NotifyPropertyChanged for changed property is not update sort order.

    Using of

    ICollectionView dataView = CollectionViewSource.GetDefaultView(myListView.ItemsSource);
    dataView.Refresh();

    is too slow and load processor too much.

  8. Oleg says:

    Nice work.
    Is there a way to use this sorting mechanism when setting lv.ItemSource to a LINQ-to-SQL query?
    How would one translate a sortBy value into “orderby …” clause?

    Thanks,

  9. ligao101 says:

    Dimitry,

    I think for a large data set, if you want to update the sort, you’ll need to unbind the datasource (ItemsSource) before updating the data, and then you can bind the source again.

    Adding large set of data into an existing, sorted gridview will be very slow without “unbind” the datasource first.

    Oleg,
    I have not tried LINQ to SQL for this case. It may work the similar way. Let me know if you have any experimental results on this. Thanks.

  10. fdsgfd says:

    where is the download ????????????????

  11. Toshendra Dalvi says:

    Good Article, but i have observed two major problems
    1) with virtualisation turned off sort is slow.
    2) as you increase number of column sort speed decrease.

  12. Sachin Gaur says:

    Hi
    How I can use this demo for visual Studio 2005. Please upload the same for VS 2005.
    I like your sorting demo but don’t have VS 2008.
    thanks
    Sachin Gaur

  13. Anjali Batra says:

    Very Nice example must say… Can we do something similar with Grouping. I mean Virtualisation along with grouping on some criteria. If yes can you give soem clues.

  14. ken says:

    Non of the download links work๐Ÿ™‚ I very much like to see how you solved it.

  15. jesuscheung says:

    hi, the links for downloading both samples are broken. pls can you fix them?

  16. saime says:

    Hi Li Gao,

    Though it would be a nice work! I couldn’t download , none of those aforementioned links are working, and I desperately needed multicolumn sorting, would be great if you can upload it again, or send it via email.

    Regards,
    Saime

  17. Daniel says:

    Could you please re-upload the samples?

    Thanks!

  18. Calin says:

    Hi,

    Download links are not available anymore, I am interested in the multiple column sort can you please reports.

    Thank you,

  19. […] that gets created when using a collection that implements an IList). Have a look here https://ligao101.wordpress.com/2007/07/31/a-much-faster-sorting-for-listview-in-wpf/. (TIP) If you need to do sorting of ListViews so that when the user clicks on the ListView Column […]

  20. Kazim Yildiz says:

    Does anyone have this sample project source code for this? It seems that the links are no longer valid.

  21. ligao101 says:

    Hi all,

    New source code link is posted at the bottom of the blog page. Sorry for the broken link.

  22. Tomsa says:

    Can you please indicate license for use?

    Your article and demo look really helpful to someone who’s learning the ropes. I have a boss who’d like me to make sure you’re putting this in the public domain; i.e. the example code can be used and adapted freely by anyone who can learn from it.

    It seems obvious from the context of your blog but need to ask.

    Thank you and have a great day.

  23. ligao101 says:

    Tomsa,

    All source code are put here under public license. Feel free to modify, change, and redistribute it.๐Ÿ™‚

    In return, I only ask for putting a credit to me in your code or product.

  24. Tomsa says:

    Thanks very much. I really appreciate the nice work you’ve done writing this content! It stands out as very helpful.

  25. sandeep says:

    Good work, But there is design issue it won’t work for two listviews bound to two differnt observable collections containing same type of objects. It works for only one listview becuase ListViewSorter is static class and can bound to only one listview.

  26. Martin Franta says:

    Right, i got the same problem as Sandeep mentioned before. Solved it with changing the static members (LastDirection, LastHeaderClicked) to DependencyPropertys and removing the static member for remembering the handling ListView. You get it within the click handler anyway.
    Thanks for the nice work ;รถ)

  27. Mario says:

    After clicking on the header of column 2, the grid is sorted by column 2. But if you then click on the header of column 1, nothing happens. This is the same with all columns: clicking on column header n+1 makes sorting by column n not work anymore. Anyway, it’s a great example. Thank you.

  28. Thanks a ton, this saved me lot of code over working around inefficient sort for 50,000 items.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: