ListView
99WPF --- Элементы управления WPF --- ListView
Класс ListView — это специализированный класс спискового типа, предназначенный для отображения различных представлений одних и тех же данных. Он особенно удобен, когда требуется создать представление, состоящее из множества столбцов и отображающее о каждом элементе данных несколько различных фрагментов информации.
Класс ListView унаследован от ListBox и дополняет его одной единственной деталью: свойством View. Свойство View представляет собой еще одну точку для создания многофункциональных списковых представлений. Если это свойство не установлено, элемент ListView ведет себя просто точно так же, как и его менее мощный предок — класс ListBox. Однако он становится гораздо более интересным, когда разработчик предоставляет объект представления, указывающий, каким должно быть форматирование и стили у элементов данных.
Формально свойство View указывает на экземпляр любого класса, унаследованного от ViewBase (который представляет собой абстрактный класс). Класс ViewBase удивительно прост: в действительности это не более чем оболочка, объединяющая вместе два стиля. Один из этих стилей применяется к элементу управления ListView (и указывается в свойстве DefaultStyleKey), в то время как другой применяется элементам внутри ListView (и указывается в свойстве ItemContainerDefaultStyleKey). Свойства DefaultStyleKey и ItemContainerDefaultStyleKey фактически стиль не предоставляют, а вместо этого они просто возвращают указывающий на него объект ResourceKey.
Сейчас наверняка интересно узнать, а зачем тогда вообще нужно свойство View — в конце концов, класс ListBox (как и все классы, унаследованные от ItemsControl) уже предлагает такие мощные возможности, как шаблоны данных и стили. Целеустремленные разработчики могут переделывать внешний вид элемента управления ListBox, предоставляя другой шаблон данных, другую панель компоновки и другой шаблон элемента управления.
Вообще говоря, для создания настраиваемых списков с множеством столбцов использовать класс ListView со свойством View необязательно. Точно такого же эффекта можно добиться и самостоятельно с помощью поддерживаемых классом ListBox шаблонов и стилей. Однако свойство View является полезной абстракцией. Ниже перечислены некоторые основные преимущества:
- Представления, пригодные для многократного использования
ListView выделяет все касающиеся представления детали в один объект. Это упрощает создание представлений, не зависящих от данных и пригодных для применения с более чем одним списком.
- Множественные представления
Отделение элемента управления ListView от объектов View также упрощает переключение между множеством различных представлений в одном и том же списке. (Например, именно такая технология применяется в проводнике Windows для получения различных представлений файлов и папок пользователя.) Точно такую же функциональную возможность можно создать и за счет динамического изменения шаблонов и стилей, но построить единственный объект, инкапсулирующий все детали представления, все-таки гораздо легче.
- Более удобная организация
Объект представления упаковывает два стиля: один для корневого элемента управления ListView и еще один — для отдельных элементов в списке. Поскольку эти стили упаковываются вместе, очевидно, что эти два фрагмента связаны между собой и могут разделять определенные детали и взаимозависимости. Например, для основанного на столбцах элемента управления ListView это имеет большой смысл, поскольку ему необходимо, чтобы размещение заголовков столбцов совпадало с размещением предназначенных для этих столбцов данных.
Применение этой модели открывает замечательные возможности для создания ряда полезных готовых представлений, которыми бы могли пользоваться все разработчики. К сожалению, в настоящее время в состав WPF входит пока только один объект представления — объект GridView. Хотя его можно и удобно использовать для построения списков с множеством столбцов, при наличии каких-то других потребностей придется создавать собственное специальное представление. В последующих разделах будет показано, как делать то и другое.
Элемент GridView будет замечательным выбором, если нужно, чтобы отображаемые данные можно было конфигурировать, а представление в стиле сетки было одной из доступных для пользователя опций. Но если требуется, чтобы в сетке дополнительно поддерживались расширенная стилизация, выбор или редактирование, придется перейти к использованию полнофункционального элемента управления DataGrid.
Создание столбцов с помощью GridView
GridView — это класс, который наследуется от ViewBase и предоставляет списковое представление с множеством столбцов. Определяются эти столбцы путем добавления в коллекцию GridViewColumns объектов GridViewColumn.
GridView и GridViewColumn предлагают небольшой набор полезных методов, которые разработчик может использовать для настройки внешнего вида своего списка. Чтобы создать самый простой прямолинейный список (вроде Details (Список) в проводнике Windows), потребуется установить для каждого объекта GridViewColumn всего лишь два свойства: Header и DisplayMemberBinding. Свойство Header отвечает за размещаемый в верхней части столбца текст, а свойство DisplayMemberBinding содержит привязку, извлекающую из каждого элемента данных подлежащий отображению фрагмент информации.
Ниже приведен код разметки, необходимый для определения трех используемых в этом примере столбцов:
<ListView Name="lstw" Margin="5">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Имя" DisplayMemberBinding="{Binding Path=ModelName}"></GridViewColumn>
<GridViewColumn Header="Модель" DisplayMemberBinding="{Binding Path=ModelNumber}"></GridViewColumn>
<GridViewColumn Header="Цена" DisplayMemberBinding="{Binding Path=UnitCost, StringFormat={}{0:C}}"></GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Здесь есть несколько важных моментов, на которые стоит обратить внимание. Во-первых, размер ни одного из столбцов не является жестко закодированным. Вместо этого GridView устанавливает размер столбцов в соответствии с размером самого широкого видимого элемента (или столбца заголовка, если тот занимает больше места в ширину), что вполне логично для основанного на гибкой компоновке мира WPF. (Конечно, при наличии огромных значений столбцов это немного усложняет дело. В таком случае можно попробовать упаковать текст).
Во-вторых, свойство DisplayMemberBinding устанавливается с использованием полнофункционального выражения привязки, которое поддерживает все возможности, в том числе форматирование строк и конвертеры значений.
Изменение размера столбцов
Изначально GridView делает каждый столбец настолько широким, насколько необходимо для того, чтобы в нем могло уместиться самое больше видимое значение. Однако размер любого столбца можно легко изменить, щелкнув и перетащив край его заголовка. Дважды щелкнув на крае заголовка столбца, можно заставить GridViewColumn изменить свой размер самостоятельно на основании какого-либо видимого в нем в текущий момент содержимого.
Например, в случае обнаружения при прокрутке списка вниз элемента, усеченного из-за несоответствия его размера ширине столбца, можно просто дважды щелкнуть на правом крае заголовка этого столбца, и столбец автоматически расширится должным образом.
Для более точного управления размером столбца при его объявлении можно указать конкретную ширину:
<GridViewColumn Width="300" ... />
Это просто определяет начальный размер столбца. На возможность пользователя изменять размер столбца описанными выше способами это никак не влияет. К сожалению, свойства вроде MaxWidth и MinWidth класс GridViewColumn не поддерживает, так что ограничить пределы, до которых пользователь может изменять размеры столбцов, нельзя. Единственный вариант — предоставить новый шаблон для заголовка GridViewColumn и вообще отключить возможность изменения его размера.