Практическое руководство. Сортировка столбцов GridView при нажатии на заголовок

В этом примере демонстрируется создание элемента управления ListView, который реализует режим отображения GridView и сортирует данные при щелчке по заголовку столбца.

Пример

В следующем примере определяется GridView с тремя столбцами, которые привязаны к Year, Month и Day, свойствам структуры DateTime.

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

В следующем примере показаны элементы данных, определенные как ArrayList объекта DateTime. ArrayList определяется как ItemsSource для элемента управления ListView.

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

Идентификаторы s и p в тегах XAML относятся к сопоставлениям пространств имен, которые определены в метаданных страницы XAML. В следующем примере показано определение метаданных.

<Window      
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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">

Для сортировки данных согласно содержимому столбца в примере определяется обработчик событий для обработки события Click, которое возникает при нажатии кнопки заголовка столбца. В следующем примере показано, как задать обработчик событий для элемента управления GridViewColumnHeader.

<ListView x:Name='lv' Height="150" HorizontalAlignment="Center" 
  VerticalAlignment="Center" 
  GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
 >

В примере определяется обработчик событий, который изменяет направление сортировки по возрастанию и по убыванию при каждом нажатии кнопки заголовка столбца. В следующем примере демонстрируется обработчик событий.

    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
public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    GridViewColumnHeader _lastHeaderClicked = null;
    ListSortDirection _lastDirection = ListSortDirection.Ascending;

    void GridViewColumnHeaderClickedHandler(object sender,
                                            RoutedEventArgs e)
    {
        GridViewColumnHeader headerClicked =
              e.OriginalSource as GridViewColumnHeader;
        ListSortDirection direction;

        if (headerClicked != null)
        {
            if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
            {
                if (headerClicked != _lastHeaderClicked)
                {
                    direction = ListSortDirection.Ascending;
                }
                else
                {
                    if (_lastDirection == ListSortDirection.Ascending)
                    {
                        direction = ListSortDirection.Descending;
                    }
                    else
                    {
                        direction = ListSortDirection.Ascending;
                    }
                }

                string header = headerClicked.Column.Header as string;
                Sort(header, direction);

                if (direction == ListSortDirection.Ascending)
                {
                    headerClicked.Column.HeaderTemplate =
                      Resources["HeaderTemplateArrowUp"] as DataTemplate;
                }
                else
                {
                    headerClicked.Column.HeaderTemplate =
                      Resources["HeaderTemplateArrowDown"] as DataTemplate;
                }

                // Remove arrow from previously sorted header
                if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
                {
                    _lastHeaderClicked.Column.HeaderTemplate = null;
                }


                _lastHeaderClicked = headerClicked;
                _lastDirection = direction;
            }
        }
    }

В следующем примере показан алгоритм сортировки, который вызывается обработчиком событий для сортировки данных. Сортировка выполняется путем создания новой структуры SortDescription.

        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
private void Sort(string sortBy, ListSortDirection direction)
{
    ICollectionView dataView =
      CollectionViewSource.GetDefaultView(lv.ItemsSource);

    dataView.SortDescriptions.Clear();
    SortDescription sd = new SortDescription(sortBy, direction);
    dataView.SortDescriptions.Add(sd);
    dataView.Refresh();
}

См. также

Ссылки

ListView

GridView

Основные понятия

Общие сведения об элементе управления ListView

Общие сведения о GridView

Другие ресурсы

Практические руководства, посвященные ListView