Главная » Разработка для Windows Phone 7 » Настройка представления элементов списков в Windows Phone 7

0

Второй из трех подходов к заполнению элемента управления списками требует явного определения содержимого в XAML. Этот подход используется в проекте ItemsControlsFromXaml (Элементы управления списками из XAML) для заполнения ItemsControl и двух элементов управления ListBox. Определенное ItemsControl свойство Items – это свойство содержимого элемента управления, поэтому в XAML требуется лишь поместить все объекты между открывающим и закрывающим тегами заданного элемента управления списками.

Ожидается, что нам потребуется форматировать некоторые строки в привязках данных. Для этого включаем StringFormatConverter в коллекцию Resources в файле MainPage.xaml приложения:

Проект Silverlight: ItemsControlsFromXaml Файл: MainPage.xaml (фрагмент)

<phone:PhoneApplicationPage.Resources>

<petzold:StringFormatConverter x:Name="stringFormat" /> </phone:PhoneApplicationPage.Resources>

В области содержимого располагается Grid с тремя столбцами:

Проект Silverlight: ItemsControlsFromXaml Файл: MainPage.xaml (фрагмент)

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.ColumnDefinitions>

<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions>

</Grid>

Первая ячейка Grid включает ScrollViewer, в котором располагается ItemsControl, в котором находятся объекты Color для всех цветов, определенных в Silverlight:

Проект Silverlight: ItemsControlsFromXaml Файл: MainPage.xaml (фрагмент)

<ScrollViewer Grid.Column="0"> <ItemsControl>

<Color>AliceBlue</Color>

<Color>AntiqueWhite</Color>

<Color>Aqua</Color>

<Color>Aquamarine</Color>

<Color>Azure</Color>

<Color>Wheat</Color>

<Color>White</Color>

<Color>WhiteSmoke</Color>

<Color>Yellow</Color>

<Color>YellowGreen</Color>

</ItemsControl> </ScrollViewer>

Исходя из нашего опыта по размещению объекта Color в Button, можно догадаться, что в результате мы получим список из 141 шестнадцатеричного значения цвета. Но по крайней мере, его можно будет прокручивать.

Для разнообразия во втором столбце Grid разместим ListBox, включающий 141 объект SolidColorBrush:

Проект Silverlight: ItemsControlsFromXaml Файл: MainPage.xaml (фрагмент)

<ListBox Grid.Column="1"

DisplayMemberPath="Color"> <SolidColorBrush Color="AliceBlue" /> <SolidColorBrush Color="AntiqueWhite" /> <SolidColorBrush Color="Aqua" /> <SolidColorBrush Color="Aquamarine" /> <SolidColorBrush Color="Azure" />

<SolidColorBrush Color="Wheat" /> <SolidColorBrush Color="White" /> <SolidColorBrush Color="WhiteSmoke" /> <SolidColorBrush Color="Yellow" /> <SolidColorBrush Color="YellowGreen" /> </ListBox>

Опять же из опыта размещения объекта SolidColorBrush в Button нам известно, что это приведет даже к еще более печальным результатам: мы получим 141 экземпляр текстовой строки с полным именем класса «System.Windows.Media.SolidColorBrush».

Но посмотрим на задание следующего свойства ListBox:

DisplayMemberPath="Color"

Это свойство определяется классом ItemsControl и позволяет задавать свойство элементов, входящих в элемент управления списками, которое будет использоваться для целей отображения. (Конечно, это целесообразно, только если все элементы одного типа, что не является обязательным требованием.) При таком значении данного свойства ListBox будет отображать не объект SolidColorBrush, а свойство Color каждого SolidColorBrush и те же шестнадцатеричные значения, что отображаются в ItemsControl.

Третий столбец ListBox описан правильно. Он включает все тот же 141 элемент SolidColorBrush, как и первый ListBox, но в нем также есть DataTemplate, заданный как значение свойства ItemTemplate, который позволяет определять формат отображения элементов:

Проект Silverlight: ItemsControlsFromXaml Файл: MainPage.xaml (фрагмент)

<ListBox Grid.Column="2"> <ListBox.ItemTemplate> <DataTemplate>

<StackPanel Orientation="Horizontal"> <Rectangle Width="48" Height="36" Margin="2" Fill="{Binding}" />

<StackPanel Orientation="Horizontal"

VerticalAlignment="Center"> <TextBlock Text="{Binding Color.R,

Converter={StaticResource stringFormat}, ConverterParameter=’ {0:X2}’}" /> <TextBlock Text="{Binding Color.G,

Converter={StaticResource stringFormat}, ConverterParameter=’-{0:X2}’}" /> <TextBlock Text="{Binding Color.B,

Converter={StaticResource stringFormat}, ConverterParameter=’-{0:X2}’}" />

</StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate>

<SolidColorBrush   Color="AliceBlue" />

<SolidColorBrush   Color="AntiqueWhite" />

<SolidColorBrush   Color="Aqua" />

<SolidColorBrush   Color="Aquamarine" />

<SolidColorBrush   Color="Azure" />

<SolidColorBrush   Color="Wheat" />

<SolidColorBrush   Color="White" />

<SolidColorBrush   Color="WhiteSmoke" />

<SolidColorBrush   Color="Yellow" />

<SolidColorBrush  Color="YellowGreen" /> </ListBox>

В этом DataTemplate значением свойства Fill объекта Rectangle задан пустой Binding:

Fill="{Binding}"

Это означает, что Fill задан конкретный элемент ListBox типа SolidColorBrush. Привязки трех элементов TextBlock ссылаются на свойства R, G и B свойства Color кисти. И хотя этот ListBox по-прежнему выводит на экран шестнадцатеричные числа, по крайне мере он делает это стильно:

В XAML можно описывать список элементов, включающий небольшое количество неизменных элементов. Я использовал эту технику для отображения 141 значения Color лишь потому, что они не могут быть сгенерированы в коде на Silverlight посредством применения технологии отражения к классу Colors. (Класс Colors в Silverlight определяет лишь 15 из этих цветов, поэтому мне пришлось написать приложение на WPF, оно сформировало разметку, которую я затем скопировал и вставил в XAML-файл Silverlight.)

Если элементы, которые требуется поместить в ItemsControl или ListBox в XAML, являются просто текстовыми строками, синтаксический анализатор XAML должен как-то различать их. Возможно, самым простым решением будет задать пространство имен XML для пространства имен System:

xmlns:system="clr-namespace:System;assembly=mscorlib"

После этого можно явно разделять элементы тегами String:

<ItemsControl>

<system:String>Item Number 1</system:String> <system:String>Item Number 2</system:String> <system:String>Item Number 3</system:String> <system:String>Item Number 4</system:String>

</ItemsControl>

Аналогичным образом с помощью тегов system:Double можно явно заполнить ItemsControl числами. При использовании ListBox, а не ItemsControl, строковые элементы можно разделять тегами ListBoxItem:

<ListBox>

<ListBoxItem>Item Number 1</ListBoxItem> <ListBoxItem>Item Number 1</ListBoxItem> <ListBoxItem>Item Number 1</ListBoxItem> </ListBox>

Ранее я говорил, что ListBox автоматически формирует объекты ListBoxItem как контейнеры. Не приведет ли такая разметка к тому, что ListBox поместит эти объекты ListBoxItem в дополнительные объекты ListBoxItem? На самом деле, нет. Специально для предотвращения этой проблемы ItemsControl определяет виртуальный метод IsItemItsOwnContainerOverride (Элемент переопределяет собственный контейнер).

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

Свойство

Тип свойства

Назначение

Template

ControlTemplate

настраивает визуальный стиль элемента управления

ContentTemplate

DataTemplate

настраивает представление содержимого

Существует три типа шаблонов, которые могут применяться к элементу управления списками, и еще один косвенно доступен для ListBox и ComboBox. Привожу их в таблице в порядке, в котором они могут встречаться в дереве визуальных элементов, сверху вниз.

 

Свойство

Тип свойства

Назначение

Template

ControlTemplate

настраивает визуальный стиль элемента управления

ItemsPanel

ItemsPanelTemplate

задает Panel, используемый для размещение элементов списка

ItemContainerStyle

Style

стиль ListBoxItem или ComboBoxItem

ItemTemplate

DataTemplate

настраивает представление самого элемента

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

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