Главная » Silverlight » Класс PagedCollectionView

0

Элемент DataGrid предоставляет ряд средств на основе класса PagedCollectionView, определенного в пространстве имен System.Windows. Data. Объект PagedCollectionView служит оболочкой коллекции, предоставляя разные способы ее просмотра. Концептуально, PagedCollectionView — это окно, выводящее данные и позволяющее применить сортировку, фильтрацию, группирование и разбиение на страницы перед выводом данных в связанный элемент управления, например DataGrid.

Чтобы применить объект PagedCollectionView, нужно явно создать его в коде и пре­доставить ему исходную коллекцию данных как аргумент конструктора. Затем нужно связать объект PagedCollectionView с соответствующим элементом управления, для которого он служит в качестве исходной коллекции.

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

gridProducts.ItemsSource = е.Result;

Вместо него вставьте следующий код.

PagedCollectionView view =new PagedCollectionView(е.Result);

gridProducts.ItemsSource = view;

Чтобы изменить способ представления данных в связанном элементе управления, настройте параметры объекта PagedCollectionView. В следующих разделах вы увидите примеры использования свойств объекта PagedCollectionView.

Сортировка

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

PagedCollectionView view =new PagedCollectionView(е.Result) ;

II Сортировка по категориям и ценам view.SortDescriptions.Add( new SortDescription("CategoryName",

ListSortDirection.Ascending)); view.SortDescriptions.Add( new SortDescription("UnitCost",

ListSortDirection.Ascending));

gridProducts.ItemsSource = view;

Такой способ хорошо согласуется со средствами сортировки, встроенными в Data- Grid (см. ранее). Элемент DataGrid отображает стрелку в заголовке каждого столбца, в котором PagedCollectionView используется для сортировки. Щелкнув на стрелке, пользователь изменяет последовательность сортировки. При этом строки автоматиче­ски переупорядочиваются.

Фильтрация

Свойство PagedCollectionView. Filter можно применить для фильтрации строк с помощью процедуры обратного вызова. Если она возвращает true, строка отображает­ся, а если false — скрывается.

В приведенном ниже примере отображаются только продукты, принадлежащие ка­тегории Travel.

PagedCollectionView view =new PagedCollectionView(e.Result);

//В исходной коллекции остается полный список продуктов, // однако продукты, не принадлежащие категории Travel, // сквозь PagedCollectionView не видны

view.Filter = delegate(object filterObject) {

Product product = (Product)filterObject; return (product.CategoryName == "Travel");

};

gridProducts.ItemsSource = view;

Группирование

Элемент DataGrid поддерживает также группирование, позволяющее расположить строки по категориям. Нужно выбрать свойство, используемое для группирования, на­пример CategoryName. Объекты, имеющие одинаковые значения данного свойства, раз­мещаются в одной группе, которая в решетке DataGrid может быть свернута (рис. 17.16).

Рис. 17.16. Продукты сгруппированы по значениям CategoryName

Для реализации группирования выберите столбец и добавьте объект PropertyGroupDescription (его класс определен в пространстве имен System. ComponentModel) в коллекцию PagedCollectionView.GroupDescription. Ниже приведен код, группирующий строки по значениям столбца CategoryName (см. рис. 17.16).

PagedCollectionView view = new PagedCollectionView(е.Result);

view.GroupDescriptions.Add(new

PropertyGroupDescription("CategoryName"));

gridProducts.ItemsSource = view;

Добавив несколько объектов PropertyGroupDescription, можно создать вложенные группы. Приведенный ниже код разбивает продукты на категории, а внутри каждой ка­тегории создает вложенные группы на основе статуса продукта.

PagedCollectionView view =new PagedCollectionView(e.Result);

view.GroupDescriptions.Add(new

PropertyGroupDescription("CategoryName"));

view.GroupDescriptions.Add(new

PropertyGroupDescription("Status"));

gridProducts.ItemsSource = view;

В решетке DataGrid каждую группу можно сворачивать и разворачивать. Сначала все группы развернуты. Вы можете программно свернуть или развернуть группы с по­мощью их методов ExpandRowGroup () и CollapseRowGroup(). Для этого нужно найти группу в коллекции PagedCollectionView.Groups. Например, следующий код сворачи­вает группу Travel.

foreach (CollectionViewGroup group in view.Groups)

{

if (group.Name == "Travel") gridProducts.CollapseRowGroup(group, true);

}

Методы CollapseRowGroup () и ExpandRowGroup () принимают два параметра: группу, которую нужно свернуть или развернуть, и булево значение, указывающее, что нужно сделать с вложенными группами — свернуть или развернуть.

Примечание. В принципе, класс PagedCollectionView может поддерживать любой связанный объект itemsControl, включая простейший ListBox. Для них поддерживаются сортировка, фильтрация и разбиение на страницы, но не группирование. Для группирования связанный элемент управления должен выводить заголовки групп. В данный момент на это способен только элемент DataGrid.

Стандартный способ группирования с помощью класса PagedCollectionView до­вольно простой: процедура группирования основана на точном совпадении значе­ний столбца. Однако иногда нужно создать более гибкие группы, например включить в группу все продукты, названия которых начинаются с заданной буквы, или продукты, цены которых находятся в заданном диапазоне. Это можно сделать с помощью свой­ства PropertyGroupDescription . Converter. Оно принимает объект IValueConverter (см. главу 16), который преобразует исходное значение в значение, необходимое для группирования. Например, для группирования на основе первой буквы в названии про­дукта IValueConverter всего лишь извлекает первую букву из полученной строки.

С помощью свойства RowGroupHeaderStyles можно изменить внешний вид заголов­ков групп. Для этого создайте объект стиля, передающий свои параметры форматиро­вания заголовку группы. Приведенная ниже разметка изменяет цвета текста и фона в заголовке группы.

<data:DataGrid.RowGroupHeaderStyles> <Style TargetType="data:DataGridRowGroupHeader"> <Setter Property="Background" Value="#FF112255" /> <Setter Property="Foreground" Value="#FFEEEEEE" /> </Style>

</data:DataGrid.RowGroupHeaderStyles>

Примечание. Стиль может изменить любое свойство класса DataGridRowGroupHeader. Однако изменить текст заголовка сложнее. Для этого нужно создать шаблон элемента управления и применить его к свойству

DataGridRowGroupHeader.Template.

Свойство RowGroupHeaderStyles является коллекцией. Это означает, что можно соз­дать много объектов Style и применить их для форматирования заголовков вложенных групп. Если предоставить более одного стиля, первый стиль будет применен к заголовку верхнего уровня, второй — к заголовку вложенной группы и т.д.

Разбиение на страницы

Элемент PagedCollectionView позволяет разбить данные на страницы, каждая из которых содержит фиксированное количество строк. Пользователь может переходить с одной страницы на другую. Разбиение на страницы полезно при выводе больших объ­емов данных.

Для конфигурирования страниц объект PagedCollectionView предоставляет два свойства.

•       PageSize. Максимальное количество записей, выводимое на странице. По умол­чанию это свойство равно 0, в результате объект PagedCollectionView не разби­вает данные на страницы и все записи выводятся вместе.

•       Pagelndex. Номер текущей страницы. Нумерация выполняется с нуля, т.е. первая страница имеет номер 0, вторая — 1 и т.д. Свойство Pagelndex может установить только пользователь. Установить его программно невозможно. Однако объект PagedCollectionView предоставляет ряд методов (MoveToFirstPage О . MoveTo- LastPage (), MoveToPreviousPage (), MoveToNextPage () и MoveToPage О), позволя­ющих программно переходить к нужной странице.

Если бы нужно было вручную создавать элементы управления для перехода с одной страницы на другую, разбиение на страницы было бы весьма трудоемкой задачей. К счастью, в Silverlight есть элемент управления DataPager, предназначенный специ­ально для этого. Вам достаточно добавить DataPager на страницу {обычно его распола­гают под элементом DataGrid), установить несколько свойств, чтобы сконфигурировать его внешний вид, и подключить его к объекту PagedCollectionView. Ниже приведена разметка, создающая объект DataPager (рис. 17.17).

<data:DataPager Margin="5,0,5,5" Grid.Row="l" x:Name="pager" PageSize="5" DisplayMode="FirstLastPreviousNextNumeric" NumericButtonCount="3" IsTotalItemCountFixed="True"> </data:DataPager>

Рис. 17.17. Использование элемента DataPager для перехода к другим страницам

Чтобы связать DataPager с PagedCollectionView, нужно добавить в код следующую строку.

pager.Source = view;

Элемент DataPager весьма интуитивный: назначение расположенных на нем кнопок такое же, как у большинства элементов навигации на многих платформах. В табл. 17.5 приведены основные свойства элемента DataPager.

Таблица 17.5. Свойства элемента DataPager

Свойство

Описание

PageCount

Установка и чтение свойства PagedCollectionView.PageCount;

позволяет задать количество записеи на странице посредством

объекта DataPager, а не PagedCollectionView

Source

Установка и чтение объекта PagedCollectionView, служащего

оболочкой для исходных данных и реализующего разбиение на

страницы

Окончание табл. 17.5

Свойство

Описание

DisplayMode

Выбор одной из шести компоновок панели с кнопками с помощью перечисления PagerDisplayMode (рис. 17.18); чтобы настроить внешний вид панели, можно также создать собственный элемент управления навигацией, непосредственно взаимодействующий с PagedCollectionVew, или применить пользовательский шаблон DataPager

Nume гі cButtonCount

Установка количества номеров страниц, приведенных на панели

DataPager; например, если NumericButtonCount=5 (это значение по умолчанию), отображено 5 кнопок с номерами страниц (сначала от 1 до 5, если общее количество страниц не меньше пяти); свойство

NumericButtonCount ни на что не влияет, если DisplayMode равно PreviousNext или FirstLastPreviousNext

NumericButtonStyle

Стиль форматирования кнопок с номерами страниц; данное свойство ни на что не влияет, если свойство DisplayMode равно PreviousNext ИЛИ FirstLastPreviousNext

AutoEddipsis

Если это свойство равно true, на последней кнопке выводится не номер страницы, а многоточие; например, если оно равно 3, то вместо 1, 2, 3 выводятся кнопки 1, 2, …; это свойство ни на что не влияет, если свойство DisplayMode равно PreviousNext или FirstLastPreviousNext

IsTotalltemCountFixed

Если равно true и текущей является последняя страница, кнопка Next (Далее) отключена; если количество страниц может изменяться вследствие добавления или удаления строк посредством кода, рекомендуется присвоить этому свойству значение false

Рис. 17.18. Варианты компоновки панели DataPager

Элемент TreeView

Класс TreeView начал свою "карьеру" в Silverlight Tbolkit и, оказавшись очень полез­ным, был перенесен в базовую сборку System. Windows. Contorls. dll версии Silverlight 3. Он позволяет выводить элементы в виде сворачиваемой древовидной структуры, как папки и файлы в проводнике Windows.

В сущности, TreeView — не более чем специализированный элемент ItemsControl, хостирующий объекты TreeViewItem. Однако каждый TreeViewItem имеет собственный хост ItemsControl, содержащий вложенные объекты TreeViewItem. Такая гибкость по­зволяет отображать древовидные структуры с произвольным количеством уровней вложенности.

Заполнение объекта TreeView

Ниже приведена разметка двухуровневой иерархической структуры, вставленной в

TreeView.

<controls:TreeView> ccontrols:TreeViewItem НеаЗег="Фрукты"> ccontrols:TreeViewItem Неагіег="Апельсиньі"/> <controls:TreeViewItem Header="BaHaHKi"/> <controls:TreeViewItem Неагіег="Яблоки"/> </controls:TreeViewItem> Ccontrols:TreeViewItem Header="0Boi4n">

ccontrols:TreeViewItem Header="KanycTa"/> Ccontrols:TreeViewItem Header="noMHHopbi"/> ccontrols:TreeViewItem Header="Orypmj"/> c/controls:TreeViewItem>

c/controls:TreeView>

Заполнять TreeView можно не только объектами TreeViewItem. В объект TreeView можно добавить почти любой элемент, включая кнопки, панели, изображения и т.д. Однако для вывода нетекстового содержимого лучше применить элемент TreeViewItem в качестве оболочки, добавив содержимое в свойство TreeViewItem.Header.

Ccontrols:TreeViewItem> Ccontrols:TreeViewItem.Header> cButton Content="3Ta кнопка находится в TreeView"> c/Button> c/controls:TreeViewItem.Header>

c/controls:TreeViewItem>

Визуально эффект тот же, что и при добавлении нетекстового элемента непосред­ственно в TreeView, однако при добавлении в элемент TreeViewItem вы получаете доступ к мощному набору его свойств (например, IsSelected — элемент выбран, IsExpanded — элемент развернут) и событий (таких, как Selected, Unselected, Expanded и Collapsed), сообщающих о том, что происходит в элементе.

Элемент TreeViewItem может отображать обычный объект данных, например объ­ект Product. Это делается так же, как и в объекте ListBox (см. главу 16). Нужно лишь записать объект данных в свойство Header, а шаблон данных, определяющий формати­рование, — в свойство HeaderTemplate.

Связанный объект TreeView

Обычно элемент TreeView не заполняют фиксированной информацией, жестко за­кодированной в разметке. Объекты TreeViewItem чаще создают программно или путем связывания с коллекцией объектов.

Заполнить TreeView данными несложно (как и любой элемент itemsControl). Достаточно установить его свойство ItemsSource. Однако при этом заполняется лишь первый уровень TreeView. Между тем, TreeView предназначен для вывода иерархиче­ских данных, в которых одни списки вложены в элементы других списков.

На рис. 17.19 первый уровень содержит объекты Category, а второй — объекты Product, принадлежащие соответствующей категории.

Элемент TreeView облегчает вывод иерархических данных. Нужно лишь задать правильный шаблон данных. Шаблон опре­деляет отношения между разными уровнями информации.

Предположим, нужно создать пример, показанный на рис. 17.19. Вы уже знакомы с классом Product, используемым для представления одного продукта, и классом Category, служащим оболочкой для коллекции объектов Product (см. главу 16). Эти же классы можно использовать с принадлежащим веб-службе методом GetCategoriesWithProducts () для создания коллекции объектов Category, каждый из которых содержит вложенную коллекцию объектов Product. Коллекция объектов Category свя­зывается с деревом таким образом, что она попадает на первый уровень. Ниже приведен код страницы, запрашивающий веб- службу и возвращающий коллекцию.

private void Page_Loaded(object sender, RoutedEventArgs e) {

StoreDbClient client = new StoreDbClient (); client.GetCategoriesWithProductsCompleted += client_GetCategoriesWithProductsCompleted; client.GetCategoriesWi thProductsAsync();

lblStatus.Text = "Contacting service …";

}

private void client_GetCategoriesWithProductsCompleted( object sender,

GetCategoriesWithProductsCompletedEventArgs e)

{

try {

treeCategoriesProducts. ItemsSource = e. Result,

lblStatus.Text =

"Результат, полученный от веб-службы.";

}

catch (Exception err) {

lblStatus.Text = "Произошла ошибка: " + err.Message;

}

)

Рис. 17.19. Иерархия категорий и продуктов

Для вывода категорий нужно создать для TreeView. ItemTemplate шаблон, обрабаты­вающий связанные объекты. В данном примере шаблон выводит полужирным шриф­том свойства CategoryName каждого объекта Category. Ниже приведен код добавления шаблона, представленного как ресурс в коллекции UserControls .Resources.

<UserControl.Resources> <common:HierarchicalDataTemplate x:Key="CategoryTemplate"> <TextBlock Text="{Binding CategoryName}"

FontWeight="Bold" />                                                         -

</common:HierarchicalDataTemplate>

</UserControl.Resources>

Обратите внимание: свойство TreeView. itemTemplate принимает объект Hierar" chicalDataTemplate, а не DataTemplate. Его преимущество в том, что он может служить оболочкой для шаблона второго уровня, извлекая коллекцию из первого уровня и предо­ставляя ее шаблону второго уровня. Для этого нужно установить свойство ItemsSource таким образом, чтобы оно идентифицировало свойство, имеющее дочерние элементы (в данном примере — коллекцию Category. Products). Свойство ItemTemplate опреде­ляет форматирование каждого объекта. Дочерние объекты Product форматируются с помощью второго шаблона HierarchicalDataTemplate, который выводит значение ModelName курсивом. Ниже приведена разметка обоих шаблонов. .

<UserControl.Resources> <common:HierarchicalDataTemplate x:Key="CategoryTemplate" ItemsSource="{Binding Products}" ItemTemplate="{StaticResource ProductTemplate}"> <TextBlock Text="{Binding CategoryName}" FontWeight="Bold" /> </common: HierarchicalDataTemplate:»

<common:HierarchicalDataTemplate x:Key="ProductTemplate"> <TextBlock FontStyle="Italic"

Text="{Binding ModelName}" /> </common:HierarchicalDataTemplate>

</UserControl.Resources>

Каждый уровень иерархии представлен одним шаблоном. Элемент, выбранный из первого шаблона, используется во втором шаблоне в качестве источника данных.

И наконец, объект TreeView определяет форматирование элементов корневого уров­ня (категорий) с помощью шаблона CategoryTemplate.

<controls:TreeView x:Name="treeCategories" Margin="5" ItemTemplate="{StaticResource CategoryTemplate}">

</controls:TreeView>

Это все, что необходимо для вывода иерархического представления категорий и про­дуктов, как на рис. 17.19.

Резюме

В этой главе вы узнали о связывании данных — ключевом средстве Silverlight. Рассмотрено создание мощных форм данных с использованием минимального объема кода С#. Минимизация объема кода достигается благодаря извлечению необходимой информации о данных из атрибутов. Формы создаются с помощью элементов управле­ния Label, DescriptionViewer и ValidationSummary, позволяющих автоматически про­верять вводимые данные на основе модели аннотирования.

Основное внимание в главе уделено мощным элементам управления данными, осо­бенно гибкому элементу DataGrid, поддерживающему форматирование и редактирова­ние решетки данных. Вы научились выполнять с его помощью фильтрацию, группи­рование и разбиение данных на страницы. В конце главы рассмотрен класс TreeView, позволяющий связывать вложенные уровни иерархии объектов данных.

На этом обсуждение связывания данных заканчивается. В следующей главе начи­нается новая тема — сохранение данных на локальном компьютере с помощью изоли­рованных хранилищ.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии