Практическое руководство. Сортировка столбцов 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