Pre-sorting a DataGrid in WPF

35,449

Solution 1

Assuming you're talking about the WPF Toolkit DataGrid control, you need only set the CanUserSortColumns property to true and then set the SortMemberPath property of each DataGridColumn in the DataGrid.

As far as sorting the collection initially, you must use a CollectionViewSource and set the sort on that and then assign that as the ItemsSource of your DataGrid. If you're doing this in XAML then it would be as easy as:

<Window.Resources>
    <CollectionViewSource x:Key="MyItemsViewSource" Source="{Binding MyItems}">
        <CollectionViewSource.SortDescriptions>
           <scm:SortDescription PropertyName="MyPropertyName"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</Window.Resources>

<DataGrid ItemsSource="{StaticResource MyItemsViewSource}">

</DataGrid>

NOTE: the "scm" namespace prefix maps to System.ComponentModel where the SortDescription class lives.

xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"

EDIT: I think enough people got help from this post, that this upvoted comment should be included in this answer:

I had to use this to get it to work:

<DataGrid ItemsSource="{Binding Source={StaticResource MyItemsViewSource}}">

Solution 2

I know this is an old post but in addition to Drew Marsh's answer and in response to DanM's issue with the column header's arrows not appearing... You need to add the SortDirection property to the DataGridColumn:

<DataGridTextColumn Header="Name" Binding="{Binding Name}" SortDirection="Ascending" />

I posted a question about this and found the answer a few days later:

ColumnHeader arrows not reflected when sorting a DataGrid in XAML

Solution 3

When you see ItemsSource doesn't support CollectionViewSource exception then you can set the DataContext of DataGrid as 'MyItemsViewSource' and ItemsSource as {Binding} like this:

<DataGrid DataContext="{StaticResource MyItemsViewSource}" ItemsSource="{Binding}">
</DataGrid>

Solution 4

When you see ItemsSource doesn't support CollectionViewSource exception, you can sort collection by Linq before you refer it to a DataGrid:

ObservableCollection<MyDataClass> myCollection = new ObservableCollection<MyDataClass>();
dataGrid.ItemsSource = from item in myCollection orderby item select item;

You have to implement IComparable interface to MyDataClass:

public class MyDataClass : IComparable<MyDataClass> {
    public int CompareTo(Classified other) {
        return other.Value.CompareTo(this.Value); // DESC
        return this.Value.CompareTo(other.Value); // ASC
    }
}
Share:
35,449

Related videos on Youtube

devuxer
Author by

devuxer

Updated on July 09, 2022

Comments

  • devuxer
    devuxer almost 2 years

    I have a DataGrid in WPF app with several columns, including a Name column. If the users switches to a particular view, I want the data to be pre-sorted by Name (and I'd like a sort arrow to appear in the Name header just as if the user had clicked that header). However, I can't find the expected properties to make this happen. I was looking for something like SortColumn, SortColumnIndex, SortDirection, etc.

    Is it possible to specify the default sort column and direction in markup (XAML) or is that not supported by the WPF Toolkit DataGrid?

    • Drew Marsh
      Drew Marsh over 14 years
      Since WPF doesn't come with a DataGrid built in, can we assume you're referring to the DataGrid that comes with WPF Toolkit (codeplex.com/wpf)???
    • devuxer
      devuxer over 14 years
      Yes, I put the wpftoolkit tag, but I guess I didn't mention it in my question. I'll add that.
  • devuxer
    devuxer over 14 years
    @Drew, thanks but the SortMemberPath just specifies which field in the data source goes with which column in the DataGrid. I need to set the current sort column (and direction). E.g., this DataGrid is currently sorted ascending by Name.
  • Drew Marsh
    Drew Marsh over 14 years
    Well that how you solve your "clicking the header column and sorting problem". I accidentally left out how to initially sort the grid, I will add to my answer now.
  • devuxer
    devuxer over 14 years
    Yes :) That's much closer to what I was looking for, thanks. The only problem is that the sort arrow doesn't appear in the header of the column the table is sorted by. I can live with that, but an arrow would make it a little clearer to the user what the sort column is. Just a note for anyone trying to do this, you need a reference to WindowsBase to use System.ComponentModel. Once you've added the reference, you need this: xmlns:scm="clr-namespace:System.ComponentModel;assembly=Wind‌​owsBase".
  • Samuel Jack
    Samuel Jack about 14 years
    I had to use <DataGrid ItemsSource="{Binding Source={StaticResource MyItemsViewSource}}"> to get this to work.
  • denis morozov
    denis morozov almost 12 years
    I keep coming back to this post (3rd time this year) because I forget to do this very important part/piece of the puzzle! Thank you for posting it.
  • DerpyNerd
    DerpyNerd over 9 years
    This actually worked for me as I was trying to order a BindlingList using Lambda. This worked, Lambda didn't!
  • Dai
    Dai over 6 years
    This does mean that the SortDirection property must manually match the columns in the SortDescription - is there any way for the DataGrid to detect the CollectionViewSource's sorting and display the indicators automatically?