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;
}
}
}