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:
August 1, 2007 at 12:49 pm |
Nice work! Are you going to make a demo project available to download for us lazy people?
Thanks,
Josh Smith
August 1, 2007 at 5:05 pm |
Thanks. I will probably make a demo for download later today
August 1, 2007 at 5:42 pm |
The demo project is uploaded to http://www.box.net/shared/2257apvyel
August 3, 2007 at 10:48 am |
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…..?
August 3, 2007 at 4:48 pm |
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.
August 3, 2007 at 5:40 pm |
[...] the meantime, Li Gao has what looks to be an excellent post on faster sorting for listviews in [...]
September 25, 2007 at 7:35 am |
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.
November 5, 2007 at 4:09 am |
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,
November 5, 2007 at 4:36 am |
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.
February 11, 2008 at 3:49 pm |
where is the download ????????????????
March 30, 2008 at 10:13 pm |
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.
April 9, 2008 at 6:13 pm |
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
September 3, 2008 at 11:59 am |
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.
September 11, 2008 at 10:22 am |
Non of the download links work
I very much like to see how you solved it.
September 30, 2008 at 6:41 pm |
hi, the links for downloading both samples are broken. pls can you fix them?
October 28, 2008 at 5:12 pm |
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
October 29, 2008 at 2:54 pm |
Could you please re-upload the samples?
Thanks!
November 12, 2008 at 1:22 pm |
Hi,
Download links are not available anymore, I am interested in the multiple column sort can you please reports.
Thank you,
November 22, 2008 at 5:29 pm |
[...] that gets created when using a collection that implements an IList). Have a look here http://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 [...]
January 8, 2009 at 2:45 am |
Does anyone have this sample project source code for this? It seems that the links are no longer valid.
January 16, 2009 at 6:44 pm |
Hi all,
New source code link is posted at the bottom of the blog page. Sorry for the broken link.
March 14, 2009 at 4:59 am |
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.
March 14, 2009 at 7:59 pm |
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.
March 16, 2009 at 1:45 am |
Thanks very much. I really appreciate the nice work you’ve done writing this content! It stands out as very helpful.
June 4, 2009 at 12:48 pm |
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.
July 16, 2009 at 11:11 am |
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 ;ö)
October 4, 2009 at 6:18 pm |
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.