Главная » Silverlight » Связывание данных

0

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

В главе 2 вы узнали о связывании двух элементов Silverlight таким образом, чтобы изменения в одном элементе влияли на другой. В данной главе рассматривается ис­пользование средств связывания для вывода, форматирования и редактирования дан­ных. Вы узнаете о способах извлечения информации, хранящейся на стороне сервера, с помощью веб-служб, о шаблонах данных, о форматировании данных с помощью пре­образователей значений. Кроме того, мы обсудим фильтрацию данных с помощью язы­ка LINQ (Language Integrated Query — язык интегрированных запросов).

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

Сравнение средств связывания данных Silverlight и WPF

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

•               Платформа Silverlight не поддерживает связывание с классами DataSet системы ADO.NET, потому что в Silverlight не включена никакая часть модели AD0.NET.

•               В Silverlight нет класса CollectionView, позволяющего изменять способ сортировки и фильтрации объектов коллекции.

•              Silverlight не поддерживает группирование данных.

•               В Silverlight нет средств поддержки интерфейса IDataErrorlnfo.

•               Преобразователи значений Silverlight могут работать только с одним свойством данных.

•               В Silverlight не разрешены селекторы, которые динамически выбирают нужный стиль или шаблон связанных данных.

•               В Silverlight нет провайдеров объектов, обеспечивающих независимое от кода связывание. Впрочем, в WPF провайдеры объектов используются редко, причем только в случаях, когда нужно быстро создать независимую от кода процедуру связывания данных XML.

•               В Silverlight нельзя определить множественное связывание с приоритетами, позволяющее выводить временные значения, в ожидании, пока будет извлечена вся информация.

Большинство из упомянутых ограничений касается средств, которые в WPF используются редко.

Привязка к объектам данных

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

Создание объекта данных

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

Объект данных — это набор некоторой информации. Любой класс может служить объектом данных, при условии что он содержит открытые свойства. Кроме них, объект данных может иметь поля и закрытые свойства, но из этих членов нельзя извлекать информацию посредством выражений связывания. Если нужно предоставить пользова­телю возможность изменять объект данных посредством связывания, свойства объекта должны быть доступными для записи.

Ниже приведен простой объект данных, инкапсулирующий информацию об одном продукте в каталоге продуктов.

public class Product

{

private string modelNumber;

public string ModelNumber {

get { return modelNumber; } set { modelNumber = value; }

}

private string modelName;

public string ModelName

{

get { return modelName; } set { modelName = value; }

}                                 To

private double unitCost;

public double UnitCost {

get { return unitCost; } set ! unitCost = value; }

}

private string description;

. public string Description {

get { return description; } set { description = value; }

}

public Product(string modelNumber, string modelName, double unitCost, string description)

ModelNumber = modelNumber; // Номер модели ModelName = modelName; // Название модели UnitCost = unitCost;         // Цена единицы продукта

Description = description; // Описание

}

// Конструктор без аргументов позволяет создать // экземпляр класса в разметке XAML public Product(){}

}

Отображение объекта данных с помощью свойства DataContext

Рассмотрим пример, показанный на рис. 16.1. На странице отображена информа­ция об одном продукте. Для отображения используется несколько текстовых блоков, вложенных в контейнер Grid.

Рис. 16.1. Вывод данных, хранящихся в объекте Product

Необходим код, создающий объект Product, информация которого выводится на экран. В данном примере объект Product жестко кодируется. Конечно, в реальных за­дачах извлекаются не жестко закодированные данные, а информация из полезных ис­точников: веб-службы, документа XML, загружаемого файла (см. главу 20) и т.д. Далее будет рассмотрен более реалистичный пример, в котором используется полнофункцио­нальная веб-служба.

Очевидно, отобразить на экране информацию, хранящуюся в объекте Product, мож­но, скопировав ее посредством кода С#.

txtModelNumber = product. TextNumber;

Однако такой способ слишком неудобен. Если понадобится изменить источник или целевой элемент, придется модифицировать код С#. К тому же, в реальных приложени­ях информация никогда не хранится в коде.

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

Например, извлечь данные из свойства Product .ModelNumber можно с помощью сле­дующего выражения связывания.

{Binding ModelNumber}

Ниже приведен пример использования выражения связывания для установки свой­ства Text текстового блока.

<TextBox Text="{Binding ModelNumber}"></TextBox>

Как видите, методика довольно простая. Для вывода страницы, показанной на рис. 16.1, необходимы четыре выражения связывания.

<Grid Name="gridProductDetails"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"x/ColumnDefinition> <ColumnDefinitionx/ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"x/RowDefinition> <RowDefinition Height="Auto"X/RowDefinition> <RowDefinition Height="Auto"X/RowDefinition> <RowDefinition Height="Auto"x/RowDefinition> <RowDefinition Height="*"X/RowDefinition> </Grid.RowDefinitions>

<TextBlock Магдіп="7">Номер модели:</TextBlock> <TextBox Margin="5" Grid.Column="l" Text="{Binding ModelNumber)"></TextBox> <TextBlock Margin="7" Grid.Row=’"l">Ha3Baroie модели: </TextBlock>

<TextBox Margin="5" Grid.Row="l" Grid.Column="l" Text=" {Binding ModelName} "></TextBox>

<TextBlock Margin="7" Grid.Row="2">UeHa единицы продукта: </TextBlock>

CTextBox Margin="5" Grid.Row="2" Grid.Column="l"

Text="{Binding UnitCost}"></TextBox> <TextBlock Margin="7,7,7,0" Grid.Row="3">OnncaHne: </TextBlock>

<TextBox Margin="7" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2"

TextWrapping="Wrap" Text="{Binding Description}"></TextBox>

</Grid>

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

В большинстве ситуаций наиболее практичный способ состоит в установке свой­ства DataContext, принадлежащего любому элементу Silverlight. В предыдущем приме­ре можно установить свойство DataContext во всех четырех текстовых блоках. Однако можно сделать проще. Если в элементе используется выражение связывания, а свойство DataContext имеет значение null (оно установлено по умолчанию), элемент ищет объект данных, перемещаясь вверх по дереву элементов. Поиск выполняется, пока элемент не найдет объект данных или не достигнет верхнеуровневого пользовательского элемента управления, представляющего страницу Silverlight. Следовательно, в предыдущем при­мере можно задать объект данных с помощью свойства DataContext контейнера Grid. Тогда во всех текстовых блоках будет использоваться один и тот же объект данных.

Ниже приведен код, создающий объект Product и устанавливающий свойство Grid. DataContext при первой загрузке страницы.

private void Page_Loaded(object sender, RoutedEventArgs e) {

Product product = new Product("AEFS100", "Переносной дефибриллятор", 77, "Анализирует электрическую " + "активность сердца и при необходимости " + "применяет электрошок. "); gridProductDetails. DataContext = product;

}

Если не выполнить этот код, информация не появится на экране. Связывание определено, однако объект данных отсутствует, поэтому элементы страницы останутся пустыми.

Совет. Обычно все связанные элементы управления размещены в одном контейнере, поэтому удобнее установить свойство DataContext один раз в контейнере, чем в каждом связанном элементе управления.

Хранение объекта данных как ресурса

Можно определить в разметке XAML объект данных как ресурс, а затем изменить каждое выражение связывания, добавив свойство Source.

Ниже приведен пример создания объекта Product как ресурса с помощью разметки.

<UserControl.Resources> <local:Product x:Key="resourceProduct" ModelNumber="AEFS100"

M0delName="nepeH0CH0ft дефибриллятор" OnitCost="77" Description="AHanH3HpyeT электрическую активность1^ сердца и при необходимости применяет электрошок. "> </local:Product>

</UserControl.Resources>

В пространстве имен проекта должен быть объявлен префикс local пространства имен XML. Например, если проект имеет имя DataBinding, в открывающий дескриптор элемента управления UserControl нужно добавить следующий атрибут.

xmlns: local="clr-namespace: DataBinding"

Чтобы выражение связывания нашло объект данных, нужно добавить свойство Source. Для установки свойства Source используется выражение StaticResource с клю­чевым именем ресурса.

CTextBox Text="{Binding ModelNumber, Source={StaticResource resourceProduct} }">

</TextBox>

К сожалению, свойство Source необходимо устанавливать в каждом выражении связывания. Поэтому, если нужно связать много элементов с одним объектом дан­ных, то лучше установить свойство DataContext контейнера. При этом для свойства DataContext тоже можно использовать ресурс StaticResource, что позволяет связать много вложенных элементов с одним объектом данных, определенным как ресурс.

<Grid Name="gridProductDetails" DataContext="{StaticResource resourceProduct}">

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

Кроме свойства Source, расширение разметки Binding поддерживает несколько дру­гих свойств, включая Mode (установка двустороннего связывания, позволяющего редак­тировать объекты данных) и Converter (преобразование значений источника перед вы­водом на экран). Оба эти свойства подробно рассматриваются далее.

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

По теме:

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