How to: Sort a GridView Column When a Header Is Clicked
This example shows how to create a ListView control that implements a GridView view mode and sorts the data content when a user clicks a column header.
The following example defines a GridView with three columns that bind to the Year, Month, and Day, properties of the DateTime structure.
<GridView> <GridViewColumn DisplayMemberBinding="{Binding Path=Year}" Header="Year" Width="100"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Month}" Header="Month" Width="100"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Day}" Header="Day" Width="100"/> </GridView>
The following example shows the data items that are defined as an ArrayList of DateTime objects. The ArrayList is defined as the ItemsSource for the ListView control.
<ListView.ItemsSource> <s:ArrayList> <p:DateTime>1993/1/1 12:22:02</p:DateTime> <p:DateTime>1993/1/2 13:2:01</p:DateTime> <p:DateTime>1997/1/3 2:1:6</p:DateTime> <p:DateTime>1997/1/4 13:6:55</p:DateTime> <p:DateTime>1999/2/1 12:22:02</p:DateTime> <p:DateTime>1998/2/2 13:2:01</p:DateTime> <p:DateTime>2000/2/3 2:1:6</p:DateTime> <p:DateTime>2002/2/4 13:6:55</p:DateTime> <p:DateTime>2001/3/1 12:22:02</p:DateTime> <p:DateTime>2006/3/2 13:2:01</p:DateTime> <p:DateTime>2004/3/3 2:1:6</p:DateTime> <p:DateTime>2004/3/4 13:6:55</p:DateTime> </s:ArrayList> </ListView.ItemsSource>
The s and p identifiers in the XAML tags refer to namespace mappings that are defined in the metadata of the XAML page. The following example shows the metadata definition.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ListViewSort.Window1" xmlns:s="clr-namespace:System.Collections;assembly=mscorlib" xmlns:p="clr-namespace:System;assembly=mscorlib">
To sort the data according to the contents of a column, the example defines an event handler to handle the Click event that occurs when you press the column header button. The following example shows how to specify an event handler for the GridViewColumnHeader control.
<ListView x:Name='lv' Height="150" HorizontalAlignment="Center" VerticalAlignment="Center" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler" >
The example defines the event handler so that the sort direction changes between ascending order and descending order each time you press the column header button. The following example shows the event handler.
Partial Public Class Window1 Inherits Window Public Sub New() InitializeComponent() End Sub Private _lastHeaderClicked As GridViewColumnHeader = Nothing Private _lastDirection As ListSortDirection = ListSortDirection.Ascending Private Sub GridViewColumnHeaderClickedHandler(ByVal sender As Object, ByVal e As RoutedEventArgs) Dim headerClicked As GridViewColumnHeader = TryCast(e.OriginalSource, GridViewColumnHeader) Dim direction As ListSortDirection If headerClicked IsNot Nothing Then If headerClicked.Role <> GridViewColumnHeaderRole.Padding Then If headerClicked IsNot _lastHeaderClicked Then direction = ListSortDirection.Ascending Else If _lastDirection = ListSortDirection.Ascending Then direction = ListSortDirection.Descending Else direction = ListSortDirection.Ascending End If End If Dim header As String = TryCast(headerClicked.Column.Header, String) Sort(header, direction) If direction = ListSortDirection.Ascending Then headerClicked.Column.HeaderTemplate = TryCast(Resources("HeaderTemplateArrowUp"), DataTemplate) Else headerClicked.Column.HeaderTemplate = TryCast(Resources("HeaderTemplateArrowDown"), DataTemplate) End If ' Remove arrow from previously sorted header If _lastHeaderClicked IsNot Nothing AndAlso _lastHeaderClicked IsNot headerClicked Then _lastHeaderClicked.Column.HeaderTemplate = Nothing End If _lastHeaderClicked = headerClicked _lastDirection = direction End If End If End Sub
The following example shows the sorting algorithm that is called by the event handler to sort the data. The sort is performed by creating a new SortDescription structure.
Private Sub Sort(ByVal sortBy As String, ByVal direction As ListSortDirection) Dim dataView As ICollectionView = CollectionViewSource.GetDefaultView(lv.ItemsSource) dataView.SortDescriptions.Clear() Dim sd As New SortDescription(sortBy, direction) dataView.SortDescriptions.Add(sd) dataView.Refresh() End Sub