Главная » Silverlight » Шаблоны данных используемые в Silverlight

0

Шаблон данных — это фрагмент разметки XAML, определяющий, как будет выведен связанный объект данных. поддерживаются элементами управления следующих видов.

•       Элементы управления, производные от класса ContentControl, поддерживают шаблоны данных посредством свойства ContentTemplate. Шаблоны используют­ся в них для вывода любого содержимого, заданного в свойстве Content.

•       Элементы управления, производные от класса ItemsControl (т.е. списки), под­держивают шаблоны данных посредством свойства ItemTemplate. Эти шаблоны используются для вывода каждого элемента коллекции (или каждой строки та­блицы DataTable), заданной в свойстве ItemsSource.

Шаблоны списков фактически основаны на шаблонах элементов ContentControl. Это объясняется тем, что каждый элемент списка вложен в оболочку элемента

ContentControl (например, ListBoxItem — в ListBox, ComboBoxItem — в ComboBox и т.д.).

Какой бы шаблон ни был задан для свойства itemTemplate списка, он используется как шаблон ContentTemplate каждого элемента списка.

Шаблон данных — это обычный блок разметки XAML. Как и любой другой блок раз­метки, шаблон может содержать любую комбинацию элементов. Кроме того, он может содержать одно или несколько выражений связывания, извлекающих информацию, ко­торую нужно вывести. В конце концов, если не включить в шаблон выражение связы­вания, все элементы списка будут одинаковыми. Естественно, такой список бесполезен.

Рассмотрение шаблонов данных начнем с базового списка, в котором шаблоны не используются (см. предыдущий пример).

<ListBox Name="lstProducts" DisplayMemberPath="ModelName">

</ListBox>

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

CListBox Name="lstProducts"> <ListBox.ItemTemplate> <DataTemplate>

<TextBlock Text="(Binding ModelName}"></TextBlock> </DataTemplate> </ListBox.ItemTemplate>

</ListBox>

Когда список связан с коллекцией продуктов (путем установки свойства ItemsSource), для каждого объекта Product создается один элемент ListBoxltem. Свойство ListBoxltem.Content содержит соответствующий объект Product, а свойство ListBoxltem. ContentTemplate — приведенный выше шаблон данных, который извлека­ет значение из свойства Product.ModelName и выводит его в элементе TextBlock.

Пока что результаты не впечатляющие. Однако теперь, когда применен шаблон дан­ных, представить данные можно любым способом. Например, приведенная ниже размет­ка создает список, в котором каждый элемент заключен в скругленную рамку и содержит два значения, причем одно значение (номер модели) выводится полужирным шрифтом.

"CListBox Name="lstProducts" HorizontalContentAlignment="Stretch" SelectionChanged="lstProducts_SelectionChanged"> <ListBox.ItemTemplate> <DataTemplate> <Border Margin="5" BorderThickness="l" BorderBrush="SteelBlue" CornerRadius="4"> <Grid Margin="3"> <Grid.RowDefinitions> <RowDefinitionx/RowDefinition> <RowDefinitionx/RowDefinition> </Grid.RowDefinitions> <TextBlock FontWeight="Bold" Text="{Binding ModelNumber}"></TextBlock> <TextBlock Grid.Row="l" Text="{Binding ModelName}"></TextBlock> </Grid> </Border> </DataTemplate> </ListBox.ItemTemplate>

</ListBox>

Когда список связан, для каждого продукта создается отдельный объект Border. В элемент Border вложен элемент Grid, выводящий два значения (рис. 16.12).

Рис. 16.12. Список, в котором используется шаблон данных

Инкапсуляция и повторное использование шаблонов данных

Как и стили, шаблоны данных часто объявляются как ресурс приложения или стра­ницы, а не внедряются в списки, в которых они применяются. Такое разделение позво­ляет создать более чистую разметку, особенно при использовании длинных, сложных шаблонов или нескольких шаблонов для одного элемента управления (см. далее). Кроме того, разделение предоставляет возможность повторного использования шаблона в не­скольких списках или элементах ContentControl, что позволяет унифицировать пред­ставление данных в разных местах пользовательского интерфейса.

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

<UserControl.Resources> <DataTemplate x:Key="ProductDataTemplate"> <Border Margi’n="5" BorderThickness="l" BorderBrush="SteelBlue" CornerRadius="4"> <Grid Margin="3"> <Grid.RowDefinitions> <RowDefinitionX/RowDefinition> <RowDefinitionX/RowDefinition> </Grid.RowDefinitions> <TextBlock FontWeight="Bold" Text="{Binding ModelNumber}"></TextBlock> <TextBlock Grid.Row="l" Text=" {Binding ModelName} " x/TextBlock> </Grid> </Border> </DataTemplate>

</UserControl.Resources>

Применить этот шаблон можно с помощью ссылки на статический ресурс.

CListBox Name="lstProducts" HorizontalContentAlignment="Stretch" ItemTemplate="{StaticResource ProductDataTemplate)"

SelectionChanged="lstProducts_SelectionChanged"x/ListBox>

Примечание. В шаблонах данных не обязательно связывать данные. Иными словами, вы не обязаны использовать свойство ItemsSource для заполнения списка шаблона. В предыдущем примере объекты Product можно добавить декларативно (в разметке XAML) или программно, вызвав метод ListBox. Items. Add (). В обоих случаях шаблон данных работает так же, как и при связывании.

Более сложные шаблоны данных

Шаблоны могут быть самодостаточными. Кроме базовых элементов, таких как TextBlock или выражения связывания, в них можно использовать любые элементы управления, они могут подключать обработчики событий, создавать разные представ­ления данных, применять анимацию и т.д.

Например, в выражении связывания можно применить преобразователь значений. Рассмотрим использование в шаблоне преобразователя ImagePathConverter (см. выше). Преобразователь принимает имя файла изображения и на его основе создает объект Bitmaplmage, содержащий изображение. Затем объект Bitmaplmage может быть связан непосредственно с элементом Image.

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

. cUserControl.Resources>

<local: ImagePathConverter x: Key=" ImagePathConverter " > </local:ImagePathConverter>

<DataTemplate x:Key="ProductDataTemplate"> <Border Margin="5" BorderThickness="l" BorderBrush="SteelBlue" CornerRadius="4"> <Grid Margin="3"> <Grid.RowDefinitions> <RowDefinitionX/RowDefinition> <RowDefinitionX/RowDefinition> <RowDefinitionX/RowDefinition> </Grid.RowDefinitions> <TextBlock FontWeight="Bold"

Text="{Binding Path=ModelNumber}"></TextBlock> CTextBlock Grid.Row="l"

Text="{Binding Path=ModelName}"></TextBlock> <Image Grid.Row="2" Grid.RowSpan="2" Source=" {Binding Path=ProductImagePath, Converter={StaticResource ImagePathConverter)}">

</Image> </Grid> </Border> </DataTemplate>

</UserControl.Resources>

В приведенной выше разметке нет ничего экзотического, однако результат намного интереснее (рис. 16.13).

Рис. 16.13. Список, содержащий изображения, основан на шаблоне данных

Примечание. Если шаблон содержит ошибку, исключение не генерируется. Элемент управления всего лишь не выводит данные, оставаясь пустым.

Изменение компоновки элементов

и селекторы стилей предоставляют полный контроль над пред­ставлением элемента списка. Однако они не позволяют управлять размещением эле­ментов списка друг относительно друга. Независимо от используемого шаблона или стиля, элемент ListBox размещает каждый элемент в отдельной строке и располагает каждую строку одна под другой.

Разместить элементы списка иначе можно, заменив контейнер, используемый в спи­ске для компоновки дочерних элементов. Для этого включите в свойство ItemsPanel блок разметки, определяющий нужную панель. В качестве панели допустимо использо­вание любого класса, производного от System.Windows.Controls.Panel, включая поль­зовательские контейнеры, реализующие специальную логику размещения.

В приведенной ниже разметке используется панель WrapPanel, входящая в состав Silverlight Tbolkit (www. codeplex. com/Silverlight) и описанная в главе 3. Она размеща­ет элементы слева направо по строкам.

CListBox Margin="7,3,7,10" Name="lstProducts" ItemTemplate="{StaticResource ProductDataTemplate}"> ?CListBox. ItemsPanel> <ItemsPanelTemplate>

<controlsToolkit: WrapPanelx/controlsToolkit: WrapPanel>

</ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>

Результат показан на рис. 16.14.

Рис. 16.14. Построчное размещение элементов списка

Резюме

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

В следующей главе будет глубже рассмотрено создание средств проверки данных. Кроме того, будет рассмотрен ряд мощных элементов управления данными — DataGrid, DataForm и TreeView.

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

По теме:

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