Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Custom Sort for DataBound WPF ListView

3.57/5 (12 votes)
7 Feb 2008CPOL3 min read 1   1  
Provides Custom Sorting for a ADO.NET bound WPF ListView

Introduction

WPF is a whole new technology to build rich user interfaces. The whole ambit of controls also provides for an easier development experience. Recently we came across an issue where we had a WPF ListView for our grid screens and which was bound to an ADO.NET dataset. The grid afforded the user the capability to sort, filter and other operations. However all fields were being sorted as text values. This threw an issue when trying to sort a column with integer values

Background

Normal sorting for an ADO.NET bound ListView uses the default sorting behavior treating all data as strings. Sample code for the same follows.

VB
Dim lv as ListView ‘assume you already have a ListView reference which is lv
Dim myView as ICollectionView = CollectionViewSource.GetDefaultView (lv.ItemsSource)
Dim mySortColumn as string = "sortcolumn" ‘Let mySortColumn let be name of column to sort on
myView.SortDescriptions.Add (new sortdescription (mySortColumn, ListSortDirection.Ascending)
myView.Refresh ()

This is the default way to sort a ListView by a column say ‘sortcolumn’ above. However what do you do when you want to perform some custom sorting on the ListView according to your own custom logic?

Solution & Code

A good reference to the behavior of WPF ListViews can be found in the article here

With reference to the article above if the binding source implements IList then you can cast the ICollectionView above to a ListCollectionView.ListCollectionView has a Customsort Property which you can assign an instance of your custom sort class which implements IComparable.

However if you have bound the ListView to an instance of IBindingList for e.g. a Dataview then ICollectionView above is a case of BindingListCollectionView which does not have a custom sort property. This view delegates the logic for sorting , filtering etc to the underlying dataview.

To implement custom sorting we thus made use of the underlying dataview which can be obtained by

VB
Dim myDataView as DataView = TryCast (myView.SourceCollection, DataView)(myView is of type ICollectionView as above)

Now create a class which implements IComparable and which will have your custom sorting logic. This class should have a overridden ToString method which returns the custom ToString representation for the class and should implement the CompareTo method. An example is below.

VB
Public class CustomComparer
Implements IComparable
Private _Value as Object ‘This is the internal value stored in the class
Public function CompareTo (value as Object) as Integer implements IComparable. CompareTo

Put your custom sorting logic here

VB
End function
Public overrides function ToString () as String 
End function
End Class

Now add a new column to the underlying datatable for the bound dataview which is of the type of the class above and add a new instance of this class for each DataRowView of the dataview for the new column..Ie.

‘ Pseudo code

VB
For each row as DataRowView in myView
Dim myNewClass as New CustomComparer()
Row(myNewColumnName) = myNewClass
Next

Next perform the same logic as above for the sorting except that for the sorting column add the new column that you have added above instead of the actual column,i.e,

VB
Dim mySortColumn as string = "sortcolumn" ‘Where mySortColumn is the name of column just added to the view above.
myView.SortDescriptions.Add (new sortdescription (mySortColumn, ListSortDirection.Ascending)
myView.Refresh ()

The view will now sort by the new column supplied and will call the CompareTo method of your custom class, i.e. CustomComparer above to perform the sorting.

Wrapping it Up

Custom Sorting can be a common requirement for grid controls. While I make no claims as to this being the only solution to the problem above this was a simple solution which got us the desired effect.

Note : Please note that the code above is just meant to give an idea of the implementation details to the user and is mostly pseudocode( using VB.NET syntax). Please develop the code in full from the examples above in your development IDEs.

License

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