Wednesday, February 2, 2011

How to Properly Sort on a WPF DataGrid Column in Code

There are a lot of blog posts and articles out there on how to apply a sort to a datagrid in code, but there are very few out there that show you how to do it properly. Most of the posts I ran into show you how to apply the sort, but the column header does not update properly. The items are sorted, but the sort indicator (tiny triangle on the header)

image

Does not appear. This can be really confusing especially if you have already sorted by another column by clicking on the column header. This makes the sort indicator appear on that column, but if you sort by a different one in the code behind, the sort indicator still shows that the grid is sorted by the first column (Thanks WPF DataGrid! Nice one!)

Well, there is a way to get it working properly. Here it is.

        private void applySortDescriptions(DataGridColumn col, ListSortDirection listSortDirection)
        {
            //Clear current sort descriptions
            MyDataGrid.Items.SortDescriptions.Clear();

            //Get property name to apply sort based on desired column
            string propertyName = getSortPropertyName(col);           

            //Add the new sort description
            MyDataGrid.Items.SortDescriptions.Add(new SortDescription(propertyName, listSortDirection));
           
            //apply sort
            applySortDirection(col, listSortDirection);           
           
            //refresh items to display sort
            MyDataGrid.Items.Refresh();
        }

        private string getSortPropertyName(DataGridColumn col)
        {
            //place logic in here that will return the name of the property to sort by (ex: return “name”; if you are sorting by the name property)

            return string.Empty;
        }

        private void applySortDirection(DataGridColumn col, ListSortDirection listSortDirection)
        {
            foreach (DataGridColumn c in PatientsViewDatGrid.Columns)
            {
                c.SortDirection = null;
            }
            col.SortDirection = listSortDirection;
        }

That should do it. Now you can sort and the column headers will show the sort indicator appropriately.

8 comments:

  1. thank you so much! it worked great!

    ReplyDelete
  2. Awesome worked great for me.

    ReplyDelete
  3. Thanks. Though how should this be wired in an MVVM pattern? Or indeed, where is the best place to call applySortDescriptions even in an event-driven code-behind pattern?

    ReplyDelete
  4. You could probably use a behavior to implement this in an MVVM pattern. I did not do that in this case, but that should work out for you.

    ReplyDelete
  5. Very Nice. It helped me. Thank You :) !!!!

    ReplyDelete
  6. Einfacher geht es nicht, klappt einwandfrei. Als Anpassung war nur der Name DataGrid zu ändern! Klaus

    ReplyDelete
  7. ListSortDirection sortDirection;
    int selectedColumnIndex;
    private void customerDataGrid_Sorting(object sender, DataGridSortingEventArgs e)
    {
    selectedColumnIndex = e.Column.DisplayIndex;
    sortDirection = (e.Column.SortDirection == ListSortDirection.Ascending ? ListSortDirection.Descending: ListSortDirection.Ascending);
    }

    private void applySortDescriptions(ListSortDirection listSortDirection)
    {
    //Clear current sort descriptions
    customerDataGrid.Items.SortDescriptions.Clear();

    //Get property name to apply sort based on desired column
    string propertyName = customerDataGrid.Columns[selectedColumnIndex].Header.ToString();

    //Add the new sort description
    customerDataGrid.Items.SortDescriptions.Add(new SortDescription(propertyName, listSortDirection));

    //apply sort
    applySortDirection(listSortDirection);

    //refresh items to display sort
    customerDataGrid.Items.Refresh();
    }

    private void applySortDirection(ListSortDirection listSortDirection)
    {
    customerDataGrid.Columns[selectedColumnIndex].SortDirection = listSortDirection;
    }

    ReplyDelete