Sorting a ListView Data Source in WPF

When you bind a collection to a selector control (Like a ListBox or ListView), internally, WPF creates a CollectionViewSource and a CollectionWiew, so you can sort an filter the data easily inside the control.

The first that you need to do is define two data templates for the column headers, one indicating when the column is sorted ascending and the other indicating when the column is sorted descending. For example the templates could be:

<DataTemplate x:Key="HeaderTemplateDescending">

  <DockPanel>

    <TextBlock HorizontalAlignment="Center"

               Text="{Binding}" />

    <Path x:Name="arrow" StrokeThickness="1"

          Fill="DarkGray" Data="M 5,10 L 15,10 L 10,5" />

  </DockPanel>

</DataTemplate>

<DataTemplate x:Key="HeaderTemplateAscending">

  <DockPanel>

    <TextBlock HorizontalAlignment="Center"

               Text="{Binding}"/>

    <Path x:Name="arrow" StrokeThickness="1"

          Fill="DarkGray" Data="M 5,5 L 10,10 L 15,5" />

  </DockPanel>

</DataTemplate>

The next step is hook the Click event of the GridViewColumnHeader, it can be done using an attached event in the ListView. In the handler of this event we will get the current sort order of the clicked column and we will change the template of the column header depending on the sort order we need.

private void OnColumnHeaderClick(object sender, RoutedEventArgs e)

{

    GridViewColumn column =

        ((GridViewColumnHeader)e.OriginalSource).Column;

    if (lastColumnSorted != null)

    {

        lastColumnSorted.HeaderTemplate = null;

    }

    SortDescriptionCollection sorts = notes.Items.SortDescriptions;

    RenderSort(sorts, column, GetSortDirection(sorts, column));

}

private void RenderSort(SortDescriptionCollection sorts,

    GridViewColumn column, ListSortDirection direction)

{

    column.HeaderTemplate =

        (DataTemplate)notes.FindResource("HeaderTemplate" + direction);

    Binding columnBinding = column.DisplayMemberBinding as Binding;

    if (columnBinding != null)

    {

        sorts.Clear();

        sorts.Add(new SortDescription(columnBinding.Path.Path, direction));

        lastColumnSorted = column;

    }

}

 

The complete code sample is here, and the sample using Linq.

4 Comments

Comments have been disabled for this content.