Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Windows Presentation Foundation.docx
Скачиваний:
43
Добавлен:
02.11.2018
Размер:
1.15 Mб
Скачать

16. Представления Данных

Примеры параграфа используют в качестве основы приложение для просмотра списка заданий с простым шаблоном данных для типа Task:

<DataTemplate DataType="{x:Type TaskView:Task}">

<Border BorderBrush="Aqua" BorderThickness="1" CornerRadius="2"

Padding="5" Margin="5">

<TextBlock FontSize="14" FontWeight="Bold" Text="{Binding Name}"/>

</Border>

</DataTemplate>

При выполнении привязки коллекции к списковому элементу управления WPF использует специальный объект, созданный на основе коллекции и называемый представлением коллекции (collection view). Представление позволяет фильтровать, сортировать и группировать данные коллекции и даёт возможность навигации по коллекции.

Представления построены на основе интерфейса ICollectionView из пространства имён System.ComponentModel. Этот интерфейс унаследован от IEnumerable и INotifyCollectionChanged. Его элементы отписаны в табл. 14.

Таблица 14

Элементы интерфейса ICollectionView

Имя

Описание

CanFilter,

CanGroup,

CanSort

Булевы свойства, которые указывают на поддержку представлением фильтрации, группировки и сортировки

Contains()

Метод для проверки вхождения элемента в представление

Culture

Объект, описывающий региональные стандарты (используется при сортировке представления)

CurrentChanging,

CurrentChanged

События, генерируемые при изменении позиции текущего элемента

CurrentItem,

CurrentPosition

Текущий элемент представления и его позиция

Filter

Функция фильтрации, описанная как Predicate<object>

GroupDescriptions

Коллекция объектов GroupDescription, описывающих условия группировки данных

Groups

Коллекция групп, имеющихся в представлении

IsCurrentAfterLast,

IsCurrentBeforeFirst

Булевы свойства, указывающие на то, что текущий элемент представления вышел за пределы инкапсулируемой коллекции

IsEmpty

Свойство равно true, если представление не содержит данных

MoveCurrentTo(),

MoveCurrentToFirst(),

MoveCurrentToLast(),

MoveCurrentToNext(),

MoveCurrentToPosition(),

MoveCurrentToPrevious()

Эти методы предназначены для изменения позиции текущего элемента представления

Refresh()

Метод для повторного создания представления по коллекции

SortDescriptions

Коллекция объектов SortDescription, описывающих критерии сортировки данных представления

SourceCollection

Коллекция, инкапсулируемая представлением

Существует четыре стандартных класса, реализующих ICollectionView: CollectionView, ListCollectionView, BindingListCollectionView (все три из пространства имён System.Windows.Data) и класс ItemCollection (пространство имён System.Windows.Controls). Выбор класса для представления диктуется источником данных:

  • Если источник данных реализует интерфейс IBindingList, создаётся объект BindingListCollectionView. Это происходит, в частности, когда источником является ADO.NET-объект DataTable. Представления BindingListCollectionView не поддерживают фильтрацию через свойство Filter, но определяют специальное строковое свойство CustomFilter.

  • Если источник данных реализует IList, создаётся объект представления ListCollectionView.

  • Если источник данных реализует только интерфейс IEnumerable, создаётся простейший объект представления CollectionView. Представления этого типа не поддерживают группировку.

Реализуем при помощи представлений фильтр для списка задач. В случае, когда списковый элемент управления уже связан с коллекцией данных, получить представление можно из свойства Items списка (тип этого свойства – ItemCollection). Добавим кнопку установки фильтра высокоприоритетных заданий и кнопку сброса фильтра. Обработчики кнопок показаны ниже:

// обработчик для кнопки установки фильтра

private void btnImportant_Click(object sender, RoutedEventArgs e)

{

// получаем представление у элемента управления lstTasks

ICollectionView view = lstTasks.Items;

// устанавливаем фильтр, используя Predicate<object>

view.Filter = new Predicate<object>(t => ((Task)t).Priority == 1);

}

// обработчик для кнопки сброса фильтра

private void btnReset_Click(object sender, RoutedEventArgs e)

{

ICollectionView view = lstTasks.Items;

// чтобы сбросить фильтр, достаточно присвоить ему null

view.Filter = null;

}

Используем представление, чтобы выполнить сортировку заданий по приоритету. Отдельный критерий сортировки описывается при помощи структуры System.ComponentModel.SortDescription. При этом указывается имя поля сортировки и направление сортировки (по возрастанию или по убыванию). Представление хранит все критерии сортировки в коллекции SortDescriptions. Ниже показан код обработчика для кнопки сортировки:

private void btnSort_Click(object sender, RoutedEventArgs e)

{

ICollectionView view = lstTasks.Items;

view.SortDescriptions.Add(

new SortDescription("Priority", ListSortDirection.Ascending));

}

Заметим, что если используется представление типа ListCollectionView, сортировку можно выполнить при помощи свойства CustomSort, которое принимает объект IComparer.

Представления позволяют группировать данные коллекции. Для этого нужно добавить объекты PropertyGroupDescription (пространство имён System.Windows.Data) в коллекцию GroupDescriptions:

private void btnGroup_Click(object sender, RoutedEventArgs e)

{

ICollectionView view = lstTasks.Items;

view.GroupDescriptions.Add(

new PropertyGroupDescription {PropertyName = "Type"});

}

Когда используется группировка, для каждой группы создаётся отдельный объект GroupItem, и все эти объекты добавляются в список. Сделать группы видимыми можно, отформатировав элемент GroupItem. Класс ItemsControl имеет свойство GroupStyle, которое предоставляет коллекцию объектов GroupStyle1. Несмотря на имя, класс GroupStyle стилем не является. Он представляет собой удобный пакет, содержащий несколько полезных параметров для конфигурирования GroupItem:

  • ContainerStyle – стиль, который должен применяться к элементу GroupItem;

  • ContainerStyleSelector – селектор стиля для GroupItem;

  • HeaderTemplate – шаблон для отображения содержимого в начале каждой группы;

  • HeaderTemplateSelector – селектор шаблона HeaderTemplate;

  • HidesIfEmpty – булево свойство, используемое для сокрытия пустых групп.

Чтобы добавить заголовок для группы, нужно установить свойство GroupStyle.HeaderTemplate. Свойство является обычным шаблоном данных. Если в шаблоне будет использоваться привязка данных, её нужно выполнять относительно предназначенного для группы объекта PropertyGroupDescription:

<ListBox Name="lstTasks" Width="250" HorizontalContentAlignment="Stretch">

<ListBox.GroupStyle>

<GroupStyle>

<GroupStyle.HeaderTemplate>

<DataTemplate>

<TextBlock Text="{Binding Path=Name}"

FontSize="14" FontWeight="Bold"

Foreground="White" Background="Green"

Margin="0,5,0,0" Padding="3" />

</DataTemplate>

</GroupStyle.HeaderTemplate>

</GroupStyle>

</ListBox.GroupStyle>

</ListBox>

Рис. 42. Список заданий с группировкой.

Класс System.Windows.Data.CollectionViewSource – это вспомогательный класс для работы с представлениями данных, который удобно использовать в разметке XAML1. Двумя наиболее важными свойствами класса CollectionViewSource являются свойство View, которое упаковывает объект представления, и свойство Source, которое указывает на источник данных. У него также имеются свойства SortDescriptions и GroupDescriptions для сортировки и группировки коллекции, и событие Filter, которое можно ис­пользовать для выполнения фильтрации. Статический метод CollectionViewSource.GetDefaultView() позволяет получить представление для указанной коллекции.