I have a WPF DataGrid bound to a CollectionViewSource that encapsulates an ObservableCollection. This CollectionViewSource has two main objectives:
1) To group each item by a specific property of T. I'm using a ValueConverter in the GroupDescription to get the grouping behaviour I want.
2) To sort the grid by a) primarily the group name (as defined above) and b) the individual group items. I'm achieving this by attaching a custom IComparer to the CollectionViewSource's 'CustomSort' property.
This works great for the most part, however as soon as a column header is clicked, the sorting logic is overridden. I don't want to disable sorting, however I was wondering if it was possible to assign a custom sorting order for a specific column?
To make things a bit clearer, suppose a user clicks 'ColumnA' - at the moment, the sorting logic encapsulated by my CustomSorter is overridden and the DataGrid is now sorted by that property. Rather than sorting by the selected property, I'd like to instead reverse the logic of the CustomSorter.
I created a couple of attached properties which handle this issue. I hope this comes in handy for someone!
First - a simple interface for your directionalised comparer. This extends IComparer but gives us one more property (SortDirection). Your implementation should use this to determine the correct ordering of elements (which would otherwise have been lost).
Next is the attached behavior - this does two things: 1) tells the grid to use custom sort logic (AllowCustomSort=true) and b) gives us the ability to set this logic at a per-column level.
To use it, implement an ICustomComparer (with a parameterless constructor) and in your XAML:
I changed @trilson86's answer so that you need only one custom sorter-class for the whole DataGrid.
First the Interface:
Next the Bevaviour-class which defines the CustomSorterProperty in such way that you can use it directly on the DataGrid, not on the DateGridRow. In HandleCustomSorting() the property SortMemberPath of the CustomSorter ist filled with the actual value from the clicked column, you can use this value in your CustomSorter to sort against the desired column.
You can use it in XAML like this:
This answer is very similar to trilson86's solution -- it was based on it -- but it accounts for
SortMemberPath
in a manner such that the values passed to your comparer are the actual values of the column, rather than the rows. This facilitates far greater re-use on your sorters. Furthermore, it eliminates the need for a custom sort interface altogether.DataGridSortBehavior.cs
Your Xaml
This should look similar to trilson86's solution as well:
you can use this in case that you adding the columns programatically .
"val1" here is the binding path for the column we added , and you can also using another line as a second sort . like this one .
Here is one way:
Usage:
DataGrid CustomSorting
Supports nested properties