Share via


SYSK 324: WPF Grid Sorting Without Any Hardcoded References

Not sure why, but all grid sorting examples I’ve been coming across have at least something hardcoded – be it the sort column name, the data source display member, or something else. Also, the samples I’ve seen create a member variable to hold the information about last sorting parameters.

 

So, I decided to create a sample that has nothing hardcoded.

 

Note: this sample assumes XML data binding.

 

 

public void Sort(Object sender, RoutedEventArgs args)

{

    if (args.OriginalSource is GridViewColumnHeader)

    {

        GridViewColumn column = (args.OriginalSource as GridViewColumnHeader).Column;

        if (column != null)

        {

            ListView list = (sender as ListView);

            ICollectionView collectionView = CollectionViewSource.GetDefaultView(list.ItemsSource);

            GridView view = list.View as GridView;

            int index = view.Columns.IndexOf(column);

            string sortBy = (view.Columns[index].DisplayMemberBinding as Binding).XPath;

            // Note: SortDescription cannot be modified after it is "sealed" (i.e. added to list.SortDescriptions)

            System.ComponentModel.ListSortDirection direction = System.ComponentModel.ListSortDirection.Ascending;

            for (int i = 0; i < collectionView.SortDescriptions.Count; i++)

            {

                System.ComponentModel.SortDescription item = collectionView.SortDescriptions[i];

                if (item.PropertyName == sortBy)

               {

                    direction = (item.Direction == System.ComponentModel.ListSortDirection.Ascending) ?

                        System.ComponentModel.ListSortDirection.Descending : System.ComponentModel.ListSortDirection.Ascending;

                    break;

                }

            }

            // We only support one sort-by at a time...

            collectionView.SortDescriptions.Clear();

            System.ComponentModel.SortDescription sd =

                new System.ComponentModel.SortDescription(sortBy, direction);

            collectionView.SortDescriptions.Add(sd);

            collectionView.Refresh();

            // Remove old arrow image

            GridViewHeaderRowPresenter hp = (args.OriginalSource as GridViewColumnHeader).Parent as GridViewHeaderRowPresenter;

            foreach (GridViewColumn c in hp.Columns)

            {

                c.HeaderTemplate = null;

            }

            // Display up/down arrow image

            if (sd.Direction == System.ComponentModel.ListSortDirection.Ascending)

                column.HeaderTemplate = Resources["HeaderTemplateArrowUp"] as DataTemplate;

            else

                column.HeaderTemplate = Resources["HeaderTemplateArrowDown"] as DataTemplate;

        }

    }

}