Главная » Разработка для Windows Phone 7 » Привязка к ItemsSource

0

Мы рассмотрели, как заполнять элемент управления списками посредством кода или с помощью списка, описанного в XAML. Также можно задать элементы с помощью свойства ItemsSource, определенного ItemsControl. Свойство ItemsSource типа Enumerable (Перечислимый), поэтому в качестве его значения можно использовать практически любой тип коллекции, включая простой массив. Однако для работы с коллекцией, элементы которой могут добавляться и удаляться динамически, очень часто применяется класс ObservableCollection (Коллекция поддающаяся наблюдению), который реализует интерфейс INotifyCollectionChanged (Уведомление об изменении коллекции). Элемент управления списками устанавливает обработчик этого события, что позволяет ему получать уведомления об изменениях коллекции и обновляться соответственно.

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

Создадим класс ColorPresenter (Презентатор цвета), который может заполнять ListBox 140 стандартными цветами (исключая Transparent) посредством единственной привязки к

ItemsSource и в то же время предоставляет свойства, позволяющие отображать эти цвета в более удобном для восприятия пользователем виде.

Остается загадкой, почему класс Colors в Silverlight определяет только 15 статических свойств типа Color, вместо 141. Это делает класс ColorPresenter довольно неуклюжим. У меня уже было приложение на WPF, в котором применялась технология отражения к WPF-классу Colors, так что я адаптировал его для формирования названий и значений цветов для передачи в этот класс. Они располагаются в статических массивах класса ColorPresenter в библиотеке Petzold.Phone.Silverlight:

Проект Silverlight: Petzold.Phone.Silverlight Файл: ColorPresenter.cs

using System;

using System.Text;

using System.Windows.Media;

namespace Petzold.Phone.Silverlight {

public class ColorPresenter {

static string[] colorNames = {

"AliceBlue", "AntiqueWhite", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood", "CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk", "Crimson", "Cyan", "DarkBlue", "DarkCyan", "DarkGoldenrod", "DarkGray", "DarkGreen", "DarkKhaki", "DarkMagenta", "Dark0liveGreen", "Dark0range", "Dark0rchid", "DarkRed", "DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkTurquoise", "DarkViolet", "DeepPink", "DeepSkyBlue", "DimGray", "DodgerBlue", "Firebrick", "FloralWhite", "ForestGreen", "Fuchsia", "Gainsboro", "GhostWhite", "Gold", "Goldenrod", "Gray", "Green", "GreenYellow", "Honeydew", "HotPink", "IndianRed", "Indigo", "Ivory", "Khaki", "Lavender", "LavenderBlush", "LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenrodYellow", "LightGray", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue", "LightSlateGray", "LightSteelBlue", "LightYellow", "Lime", "LimeGreen", "Linen", "Magenta", "Maroon", "MediumAquamarine", "MediumBlue", "Medium0rchid", "MediumPurple", "MediumSeaGreen", "MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue", "MintCream", "MistyRose", "Moccasin", "NavajoWhite", "Navy", "0ldLace", "0live", "0liveDrab", "0range", "0rangeRed", "0rchid", "PaleGoldenrod", "PaleGreen", "PaleTurquoise", "PaleVioletRed", "PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple", "Red", "RosyBrown", "RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver", "SkyBlue", "SlateBlue", "SlateGray", "Snow", "SpringGreen", "SteelBlue", "Tan", "Teal", "Thistle", "Tomato", "Turquoise", "Violet", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen"

static uint[] uintColors = {

0xFFF0F8FF,               0xFFFAEBD7,  0xFF00FFFF,  0xFF7FFFD4, 0xFFF0FFFF,

0xFFF5F5DC,               0xFFFFE4C4,  0xFF000000,  0xFFFFEBCD, 0xFF0000FF,

0xFF8A2BE2,               0xFFA52A2A,  0xFFDEB887,  0xFF5F9EA0, 0xFF7FFF0 0,

0xFFD2 6 91E,             0xFFFF7F50,  0xFF6495ED,  0xFFFFF8DC, 0xFFDC143C,

0xFF00FFFF,               0xFF00008B,  0xFF008B8B,  0xFFB8860B, 0xFFA9A9A9,

0xFF0 0 64 0 0,           0xFFBDB7 6B, 0xFF8B008B,  0xFF556B2F, 0xFFFF8C0 0,

0xFF9932CC,               0xFF8B0000,  0xFFE9967A,  0xFF8FBC8F, 0xFF483D8B,

0xFF2F4F4F,               0xFF0 0CED1, 0xFF9400D3,  0xFFFF1493, 0xFF0 0BFFF,

0xFF696969,               0xFF1E90FF,  0xFFB22222,  0xFFFFFAF0, 0xFF228B22,

0xFFFF00FF,               0xFFDCDCDC,  0xFFF8F8FF,  0xFFFFD7 0 0, 0xFFDAA52 0,

0xFF808080,      0xFF008000, 0xFFADFF2F,   0xFFF0FFF0,  0xFFFF69B4,

0xFFCD5C5C,      0xFF4B0082, 0xFFFFFFF0,   0xFFF0E68C,  0xFFE6E6FA,

0xFFFFF0F5,      0xFF7CFC0 0, 0xFFFFFACD,  0xFFADD8E6,  0xFFF08080,

0xFFE0FFFF,      0xFFFAFAD2, 0xFFD3D3D3,   0xFF90EE90,  0xFFFFB6C1,

0xFFFFA07A,      0xFF2 0B2AA, 0xFF87CEFA,  0xFF778899,  0xFFB0C4DE,

0xFFFFFFE0,      0xFF00FF00, 0xFF32CD32,   0xFFFAF0E6,  0xFFFF00FF,

0xFF800000,      0xFF66CDAA, 0xFF0000CD,   0xFFBA55D3,  0xFF9370DB,

0xFF3CB371,      0xFF7B68EE, 0xFF00FA9A,   0xFF4 8D1CC, 0xFFC71585,

0xFF19197 0,     0xFFF5FFFA, 0xFFFFE4E1,   0xFFFFE4B5,  0xFFFFDEAD,

0xFF000080,      0xFFFDF5E6, 0xFF808000,   0xFF6B8E23,  0xFFFFA500,

0xFFFF4 50 0,    0xFFDA7 0D6, 0xFFEEE8AA,  0xFF98FB98,  0xFFAFEEEE,

0xFFDB7 0 93,    0xFFFFEFD5, 0xFFFFDAB9,   0xFFCD853F,  0xFFFFC0CB,

0xFFDDA0DD,      0xFFB0E0E6, 0xFF800080,   0xFFFF0000,  0xFFBC8F8F,

0xFF416 9E1,     0xFF8B4 513, 0xFFFA8072,  0xFFF4A460,  0xFF2E8B57,

0xFFFFF5EE,      0xFFA0522D, 0xFFC0C0C0,   0xFF87CEEB,  0xFF6A5ACD,

0xFF7 0 8 0 90,  0xFFFFFAFA, 0xFF00FF7F,   0xFF4682B4,  0xFFD2B4 8C,

0xFF008080,      0xFFD8BFD8, 0xFFFF6347,   0xFF40E0D0,  0xFFEE82EE,

0xFFF5DEB3,      0xFFFFFFFF, 0xFFF5F5F5,   0xFFFFFF0 0, 0xFF9ACD32

// Статический конструктор

static ColorPresenter() {

Colors = new ColorPresenter[14 0];

for (int i =      0; i < 140; i++) {

// Раскладываем значение цвета           на компоненты

byte A =          (byte)((uintColors[i]  &  0xFF000000) >> 24);

byte R =          (byte)((uintColors[i]  &  0x00FF0000) >> 16);

byte G =          (byte)((uintColors[i]  &   0x0000FF00) >> 8);

byte B =          (byte)((uintColors[i]  &   0x000000FF) >> 0);

// Создаем отображаемое имя для цвета StringBuilder builder = new StringBuilder();

foreach (char ch in colorNames[i]) {

if (builder.Length == 0 || Char.IsLower(ch)) builder.Append(ch);

else {

builder.Append(‘ ‘); builder.Append(ch);

}

}

// Создаем ColorPresenter для каждого цвета ColorPresenter clrPresenter = new ColorPresenter(); clrPresenter.Color = Color.FromArgb(A, R, G, B); clrPresenter.Name = colorNames[i]; clrPresenter.DisplayName = builder.ToString(); clrPresenter.Brush = new SolidColorBrush(clrPresenter.Color);

// Добавляем его в статический массив Colors[i] = clrPresenter;

}

}

public static ColorPresenter[] Colors { protected set; get; }

public Color Color { protected set; get; }

public string Name { protected set; get; }

public string DisplayName { protected set; get; }

public Brush Brush { protected set; get; }

public override string ToString() {

return Name;

}

}

}

В конце этого фрагмента мы видим открытые свойства экземпляров, предоставляемые ColorPresenter: Color типа Color, Brush типа Brush, а также Name типа string и DisplayName (Отображаемое имя). Свойство DisplayName преобразовывает стандартные имена, записанные одним словом с применением нотации «camel», в несколько слов. Например, «AliceBlue» становится «Alice Blue».

ColorPresenter также предоставляет открытое статическое свойство Colors (Цвета). Это массив, включающий все 140 объектов ColorPresenter. Этот массив и все его содержимое создается в статическом конструкторе класса.

Если бы ColorPresenter использовался исключительно в коде, нам не пришлось бы создавать никаких дополнительных экземпляров этого класса. Для получения всех 140 объектов ColorPresenter можно было бы просто выполнять доступ к статическому свойству ColorPresenter.Colors.

Но Silverlight не обеспечивает возможности доступа к статическому свойству в XAML без создания экземпляра класса, включающего это свойство, поэтому в проекте ColorPresenterDemo (Демонстрация презентатора цвета) класс ColorPresenter включен в коллекцию Resources:

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

<phone:PhoneApplicationPage.Resources>

<petzold:ColorPresenter x:Key="colorPresenter" /> <petzold:StringFormatConverter x:Key="stringFormat" /> </phone:PhoneApplicationPage.Resources>

У экземпляра ColorPresenter, созданного в XAML-файле, не будет никаких полезных свойств экземпляра, но приложению необходимо только его статическое свойство Colors.

В Grid для содержимого только две строки: одна для размещения ListBox, и другая – для TextBlock с привязками к ListBox. Обратите внимание, что свойство ItemsSource класса ListBox связано посредством привязки со свойством Colors ресурса ColorPresenter. Благодаря этой привязке ListBox заполняется 140 объектами типа ColorPresenter, благодаря чему DataTemplate может иметь привязки к свойствам DisplayName и Color этого класса:

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

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

<RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions>

<ListBox Grid.Row="0"

Name="listBox"

ItemsSource="{Binding Source={StaticResource colorPresenter}, Path=Colors}">

<ListBox.ItemTemplate> <DataTemplate> <Grid>

<Grid.ColumnDefinitions>

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

<Rectangle Grid.Column="0"

Fill="{Binding Brush}" Width="72" Height="4 8" Margin="2 2 6 2" />

<StackPanel Grid.Column="1"

Orientation="Horizontal" VerticalAlignment="Center">

<TextBlock Text="{Binding DisplayName}" />

<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> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

<TextBlock Grid.Row="1"

FontSize="{StaticResource PhoneFontSizeExtraLarge}"

HorizontalAlignment="Center"

Margin="12"

Text="{Binding ElementName=listBox,

Path=SelectedItem.DisplayName}"

Foreground="{Binding ElementName=listBox,

Path=SelectedItem.Brush}" />

</Grid>

Свойство SelectedItem также типа ColorPresenter, так что TextBlock может ссылаться на свойства ColorPresenter для привязок к Text и Foreground:

Отображение имен цветов в пользовательском интерфейсе выбора цвета – довольно полезная функция, реализацией которой не стоит пренебрегать. Пользователи, имеющие опыт работы с цветами в HTML, будут очень признательны за это.

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

По теме:

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