Глава 5. Привязка данных
Введение
Глава 1. Модель приложения Longhorn
Глава 2. Создание приложения Longhorn
Глава 3. Элементы управления и XAML
Глава 4. Хранилище
Глава 5. Привязка данных
Брент Проректор
Мудрая сова Консалтинг
Февраль 2004 г.
Содержимое
Создание привязки данных
Типы привязки данных
Преобразователи
Предоставление уведомлений об изменении свойств
Сводка
Привязка данных в традиционном смысле означает связывание некоторых базовых данных с одним или несколькими элементами пользовательского интерфейса. Данные предоставляют информацию для отображения. Элементы пользовательского интерфейса отображают сведения в соответствующем формате.
Longhorn расширяет традиционную идею привязки данных несколькими способами. Свойство элемента пользовательского интерфейса можно привязать к свойству любого объекта СРЕДЫ CLR или к атрибуту XML-узла.
Привязка данных может быть однонаправленной (в любом направлении) или двунаправленной. Например, традиционная привязка данных содержит сведения в потоке источника данных к связанному элементу пользовательского интерфейса. Кроме того, сведения в элементе пользовательского интерфейса могут передаваться обратно в источник данных. Двунаправленная привязка данных, конечно, поддерживает поток информации в каждом направлении и позволяет пользователю ввести данные через элемент пользовательского интерфейса для обновления данных в источнике данных.
Привязка данных также может быть статической (только один раз) или динамической. При использовании статической привязки данных передача информации происходит при первоначальном создании привязки данных. Последующие изменения значений в данных не влияют на значение в элементе пользовательского интерфейса. Динамическая привязка данных позволяет распространять изменения данных в источнике данных на элемент пользовательского интерфейса и наоборот.
Привязка данных Longhorn также поддерживает преобразование данных при их поступлении в источник данных и элементы пользовательского интерфейса. Это преобразование позволяет автору приложения добавлять семантику пользовательского интерфейса к данным.
Некоторые типичные преобразования могут быть следующими:
- Отображение отрицательных чисел красным цветом и положительных чисел черным
- Отображение изображений на основе контакта в сети или в автономном режиме
- Создание динамических линейчатых диаграмм путем привязки высоты прямоугольника к цене акций
- Анимация положения изображения путем привязки его координат к свойству объекта CLR
Привязка данных Longhorn также является принципиально асинхронной. Элемент пользовательского интерфейса получает событие, когда новый источник данных привязывается к элементу . Кроме того, когда источник данных собирает свои данные, он запускает события, указывающие, что его содержимое изменилось.
Можно выполнить привязку данных к любому объекту CLR или XMLnode, поэтому можно легко привязать данные к различным моделям данных в Longhorn — объектам CLR, XML, ADO.NET наборам данных, сообщениям веб-службы или объектам WinFS. Longhorn также предоставляет ряд встроенных классов источников данных, которые позволяют легко и декларативно переносить данные в приложение. Существуют определенные источники данных для объектов XML, .NET, ADO.NET наборов данных и объектов WinFS. Модель источника данных расширяема, поэтому при необходимости можно создавать собственные пользовательские классы источников данных.
Создание привязки данных
Динамическое свойство элемента пользовательского интерфейса можно привязать к свойству любого объекта CLR. Для этого необходимо описать требуемое соответствие между каким-то элементом источника данных и целевым элементом пользовательского интерфейса. В каждой такой корреспонденции или привязке должно быть указано следующее:
- Элемент источника данных
- Путь к соответствующему значению в элементе источника данных
- Целевой элемент пользовательского интерфейса
- Соответствующее свойство целевого элемента пользовательского интерфейса
Привязка данных
Платформа представляет привязку данных экземпляром класса MSAvalon.Data.Bind . Этот класс имеет ряд свойств, управляющих привязкой данных: Path, BindType, UpdateType, Transformer, Culture, BindFlags и Source.
Для свойства Path задается строка, указывающая свойство или значение в источнике данных, к которому привязывается объект привязки. Свойство BindType управляет направлением и частотой привязки данных. Это должно быть одно из трех значений: OneWay, TwoWay и OneTime. Тип привязки OneWay приводит к тому, что привязка данных передает новые значения из источника данных в целевое свойство, но не распространяет изменения целевого свойства обратно в источник данных. Тип привязки TwoWay распространяет изменения в обоих направлениях. При указании типа привязки OneTime привязка данных передает значение из источника данных целевому свойству только при первой активации привязки.
Для свойства Transformer можно задать любой объект, реализующий интерфейс IDataTransformer . Когда привязка данных распространяет значение, она передает значение через преобразователь. Преобразователь проверяет входящее значение и создает новое значение в качестве выходных данных. Обратите внимание, что входные и выходные значения не обязательно должны быть одного типа. Вы можете использовать целочисленный флаг в качестве входных данных и создавать различные файлы изображений в качестве выходных данных.
Свойство UpdateType определяет, когда изменения целевого свойства распространяются обратно на источник данных, если тип привязки — TwoWay. Можно указать одно из трех значений: Интерпретация означает распространение нового значения в источник данных сразу после изменения целевого свойства; OnLostFocus означает распространение значения, когда целевой элемент управления теряет фокус ввода; и Явное означает, что нужно дождаться, пока код не вызовет объект привязки и сообщит ему о распространении нового значения.
Свойство Source ссылается на элемент исходных данных привязки. Чтобы задать свойство Source объекта привязки, можно использовать атрибуты DataSource, ElementSource, DataContextSource или ObjectSource . Атрибут ElementSource используется, чтобы задать для source значение Element, указав идентификатор элемента в качестве значения атрибута ElementSource . Атрибут DataContextSource позволяет задать в качестве источника контекст данных другого элемента, задав для идентификатора элемента значение DataContextSource. Атрибут ObjectSource используется для указания объекта в качестве источника привязки. Наконец, атрибут DataSource позволяет задать для свойства Source значение Dataобъекта DataSource. Это будет подробно рассмотрено в разделе Элемент источника данных.
Свойство Culture позволяет указать CultureInfo для привязок, которые должны учитывать язык и региональные параметры.
Свойство BindFlags поддерживает одно ненулевое значение: NotifyOnTransfer. Очень важно понимать, что привязка данных по своей природе является асинхронной. При изменении значения в источнике данных соответствующее целевое свойство не получает обновленное значение сразу. Для распространения нового значения на целевое свойство может потребоваться произвольное количество времени. Если необходимо узнать, когда привязка завершила обновление целевого свойства, задайте для свойства BindFlags значение NotifyOnTransfer . После обновления целевого свойства привязка данных срабатывает событие MSAvalon.Data.DataTransfer .
Определение выражения привязки с помощью кода
Вы можете создать привязку данных программным способом, хотя я ожидаю, что вам это редко понадобится или требуется. Просто создайте экземпляр класса Bind и вызовите метод SetBinding. Вот один из возможных примеров:
using MSAvalon.Data;
Bind binding = new Bind ();
binding.Path = path;
binding.BindType = bindType;
binding.Source = source;
binding.UpdateType = updateType;
element.SetBinding (property, binding);
Кроме того, вот еще один способ написания предыдущего кода с помощью одного из удобных конструкторов класса Bind:
using MSAvalon.Data;
Bind binding = new Bind (path, bindType, source, updateType);
element.SetBinding (property, binding);
Вы можете использовать другие удобные методы, такие как метод SetBinding для элемента, и упростить предыдущий код:
element.SetBinding (property, path, bindType, source, updateType);
Определение выражения привязки с помощью разметки
Я ожидаю, что вы предпочли бы определить большинство привязок данных с помощью разметки. Все предыдущие понятия по-прежнему применяются: вы создаете объект Bind , присваиваете его свойствам соответствующие значения и связываете его со свойством целевого элемента. Например, следующая разметка создает объект Bind в качестве значения свойства Text объекта Button.
<DockPanel xmlns="https://schemas.microsoft.com/2003/xaml" />
<DockPanel.Resources>
<myNameSpace:Person def:Name="MyPerson" Name="Bob"/>
</DockPanel.Resources> . . .
<Button>
<Button.Content>
<Bind Path="Name" BindType="OneWay" ObjectSource="{MyPerson}" />
</Button.Content>
</Button>
Чтобы связать привязку данных со свойством конкретного элемента пользовательского интерфейса, используйте привязку данных в качестве значения свойства . В только что показанном примере привязка данных привязывает ресурс MyPerson к свойству Text элемента Button , так как я определил привязку данных между начальным и конечным тегами Button.Text .
Свойство DockPanel Resources объявляет, что следующие дочерние элементы являются ресурсами. В отличие от обычных элементов XAML, которые создаются, когда среда выполнения анализирует XAML-файл, среда выполнения не создает экземпляр ресурса, пока вы фактически не используете его.
В предыдущем примере источником привязок является объект Person , поэтому экземпляр Bind ссылается на этот экземпляр объекта Person .
Атрибут Path указывает путь в элементе источника данных к нужному значению. В предыдущем примере путь просто Name, поэтому привязка получает свойство Name экземпляра Person . Однако путь может быть более сложным. Например, если свойство Name возвращает объект с дополнительной структурой, путь может быть таким, как Name.FirstName.
В предыдущем примере показано, как определить привязку данных с помощью сложного определения свойства для значения свойства Button.Text . Однако для выражения привязки данных можно использовать альтернативное и значительно более компактное определение. В этом случае строка определяется как выражение привязки данных. Строка начинается с символа звездочки, который компилятор XAML интерпретирует как escape-символ, а затем имя класса для создания экземпляра, а затем, заключенного в круглые скобки, ряда пар имен значений, разделенных точкой с запятой.
<DockPanel >
§
<Button Text="*Bind(Path=Name;BindType=OneWay)" />
§
</DockPanel>
Если вы определяете привязку данных, но не задаете значение для свойства Source (с помощью DataSource, ElementSource, DataContextSource или ObjectSource), привязка данных извлекает источник данных из свойства DataContext для текущего элемента. Если текущий элемент не имеет DataContext, объект привязки рекурсивно извлекает DataContext родительского элемента. Это позволяет определить источник данных один раз в соответствующем элементе в разметке, а затем использовать его в различных привязках к дочерним элементам.
В следующем примере я задал свойству DataContext элемента DockPanel привязку данных, которая ссылается на мой источник данных. По сути, все дочерние элементы наследуют это свойство DataContext , если они не присваивают ему другое значение. Так как привязки данных в элементах Button не указывают значение свойства Source , привязка использует источник из унаследованного dataContext. Конечно, вы всегда можете указать источник, чтобы определенная привязка данных использовала другой источник данных.
<DockPanel xmlns="http:////schemas.microsoft.com//2003//xaml//"
DataContext="{MyPerson}>
§ <Button Text='*Bind(Path="Name";BindType="OneWay")' />
<Button Text='*Bind(Path="Age";BindType="OneWay")' />
§</DockPanel>
Типы привязки данных
Конкретная привязка данных может быть трех типов: OneTime, OneWay и TwoWay. При объявлении привязки свойству BindType присваивается одно из перечисленных значений.
Привязка данных One-Time
При запросе однократной привязки данных среда выполнения, используя источник данных и указанный путь, извлекает исходное значение и инициализирует указанное целевое свойство этим значением. Обычно при изменении значения исходного или целевого свойства ничего не происходит.
Однако существует два особых случая. При изменении DataContext элемента источник данных изменился, поэтому привязка выполняет еще одну разовую передачу. Кроме того, во многих случаях контекст данных ссылается на коллекцию объектов . При изменении текущего объекта коллекции привязка данных выполняет однократную передачу.
Привязка данных One-Way
При запросе односторонняя привязка данных среда выполнения извлекает исходное значение и инициализирует указанное целевое свойство этим значением. При каждом изменении исходного значения привязка данных получает новое значение и повторно инициализирует целевое свойство.
Привязка данных Two-Way
При запросе двусторонней привязки данных среда выполнения извлекает исходное значение и инициализирует указанное целевое свойство этим значением. При каждом изменении исходного значения привязка данных извлекает новое значение и повторно инициализирует целевое свойство. Кроме того, при изменении значения целевого свойства ( например, при вводе пользователем в элемент управления редактированием) привязка данных извлекает новое значение целевого свойства и распространяет его обратно в источник. Двусторонняя привязка данных — это тип привязки данных по умолчанию.
Преобразователи
Преобразователь позволяет преобразовывать значение из одной формы в другую по мере его распространения в источник данных и из него в целевой объект. Преобразователь можно использовать для преобразования значения из его внутреннего представления в уникальное отображаемое значение. Например, преобразователь можно использовать для отображения отрицательного числа с плавающей запятой с использованием красного текста и положительного числа с черным текстом. Вы также можете отображать различные значки для различных рейтингов, достойных кредита для клиента.
Преобразователь также можно использовать в качестве преобразователя типов данных. Например, исходным значением может быть объект Point , а для свойства, к которому требуется привязать значение, требуется экземпляр Length .
Преобразователь также получает сведения о языке и региональных параметрах для пользовательского интерфейса в качестве одного из его параметров. Эти сведения можно использовать для адаптации представленного пользовательского интерфейса в соответствии с текущим языком и региональными параметрами пользователя. Например, можно предоставить различные значки при выполнении с разными языками и региональными параметрами.
Интерфейс IDataTransformer
Преобразователь — это любой объект, реализующий интерфейс IDataTransformer . Вот определение интерфейса:
interface IDataTransformer {
object Transform (object o, DependencyID id, CultureInfo culture);
object InverseTransform (object o, PropertyInfo pInfo, CultureInfo culture);
}
Привязка данных вызывает метод Transform при распространении исходного значения в целевое свойство. Параметр o — это исходное значение, идентификатор параметра определяет целевое свойство, а язык и региональные параметры — язык и региональные параметры для преобразования.
Привязка данных вызывает метод InverseTransform при распространении измененного значения целевого свойства обратно в источник. В этом случае параметр o является значением измененного целевого свойства, а pInfo определяет тип, в который необходимо преобразовать значение. Как и раньше, язык и региональные параметры — это культура для преобразования.
Оба метода позволяют возвращать значение NULL , чтобы указать, что привязка не должна распространять значение в соответствующем направлении. Ниже приведен простой преобразователь, который возвращает цвет на основе целочисленного значения:
<SimpleText Text="*Bind(Path=Name)" Foreground="*Bind(Path=Age; Transformer=AgeToColorTransformer)"/>
public class AgeToColorTransformer: IDataTransformer {
public object Transform (object o, DependencyID di, CultureInfo culture) {
int age = (int) o;
if (age < 0 || age > 120) return Grey;
if (age <= 30) return Green;
if (age <= 70) return Gold;
if (age <= 120) return Red;
}
public object InverseTransform (object o, PropertyInfo i, CultureInfo c) {
return null;
}
}
Предоставление уведомлений об изменении свойств
Среда CLR не предоставляет объекту универсальный способ уведомления клиентов об изменении одного из его свойств. Тем не менее, для динамической привязки требуются такие уведомления, чтобы привязка ранее распространяла измененные значения свойств на целевое динамическое свойство. Longhorn представляет интерфейс IPropertyChange , позволяющий объекту сигнализировать, когда одно из его свойств изменяет значение. Обратите внимание, что интерфейс определяет одно событие типа PropertyChangedEventHandler и что обработчик событий может получить имя измененного свойства с помощью свойства PropertyName второго параметра в обработчик.
interface IPropertyChange {
event PropertyChangedEventHandler PropertyChanged;
}
delegate void PropertyChangedEventHandler (object sender,
PropertyChangedEventArgs e);
class PropertyChangedEventArgs : EventArgs {
public virtual string PropertyName { get ;}
}
В следующем коде я переписал класс Person из предыдущей главы для поддержки изменения свойств Name и Age и для запуска соответствующих событий при таких изменениях.
namespace MyNamespace {
public class Person : IPropertyChange {
private string m_name;
private int m_age;
public event PropertyChangedEventHandler PropertyChanged;
public string Name {
get { return m_name; }
set {
if (m_name != value) {
m_name = value;
RaisePropertyChangeEvent ("Name");
}
}
}
public int Age {
get { return m_age; }
set {
if (m_age != value) {
m_age = value;
RaisePropertyChangeEvent ("Age");
}
}
}
private void RaisePropertyChangedEvent (string propertyName) {
if (PropertyChanged != null)
PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
}
public Person (string name, int age) {
m_name = name; m_age = age;
}
}
}
Объект реализует этот интерфейс, вызывая делегат PropertyChanged всякий раз, когда одно из его "интересных" свойств изменяет значение. Обратите внимание, что делегат необходимо вызывать только в том случае, если свойство, используемое в динамической привязке, изменяет значение. Объект может иметь свойства, для которых вы не срабатываете уведомления об изменениях.
Из соображений производительности следует запускать уведомления об изменениях только в том случае, если значение свойства действительно изменилось. Если объект не знает, какое значение изменилось, он может запросить обновление всех привязок к какому-либо свойству или передать String.Empty для измененного имени свойства.
Элемент источника данных
Longhorn предоставляет набор встроенных источников данных, которые позволяют легко и декларативно получать данные в приложение асинхронно без блокировки пользовательского интерфейса.
Элемент источника данных — это любой объект, реализующий интерфейс IDataSource .
interface IDataSource {
public virtual Object Data { get; }
public virtual void Refresh()
}
Этот интерфейс имеет свойство Data , которое позволяет привязке получать данные из элемента источника данных. Метод Refresh позволяет привязке запрашивать получение данных элементом источника данных, если он недоступен. Longhorn предоставляет ряд классов источников данных, и некоторые из них вы увидите в ближайшее время.
Как правило, реализация источника данных также предоставляет строго типизированное свойство, которое возвращает собственный API поставщика данных. Например, классы SqlDataSource и XmlDataSource предоставляют свойства DataSet и Document соответственно:
class SqlDataSource : IDataSource, … {
§ DataSet DataSet { get; }
§}
class XmlDataSource : IDataSource, … {
§ XmlDocument Document { get; }
§}
Таким образом, если это действительно необходимо, вы можете напрямую получить доступ к базовому поставщику данных.
Использование любого объекта CLR в качестве источника данных
Класс ObjectDataSource позволяет создать экземпляр указанного типа в качестве элемента источника данных. Как правило, вы используете XAML и объявляете источники данных в качестве ресурсов в разметке. Например, предположим, что у меня есть следующее определение класса Person в сборке с именем MyAssembly и что я хотел бы использовать экземпляр этого класса в качестве элемента источника данных:
namespace MyNamespace {
public class Person {
private string m_name;
private int m_age;
public string Name { get { return m_name; } }
public int Age { get { return m_age; } }
public Person (string name, int age) {
m_name = name; m_age = age;
}
}
}
Класс Person не нуждается в дополнительной поддержке, чтобы быть элементом источника данных. Я могу использовать экземпляр класса ObjectDataSource в качестве элемента источника данных и сообщить ему, что базовым поставщиком данных должен быть экземпляр класса Person . Для этого можно использовать разметку для объявления экземпляра ObjectDataSource в качестве ресурса XAML.
<DockPanel>
<DockPanel.Resources>
<ObjectDataSource def:Name ="source1"
TypeName="MyNamespace.Person, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0123456789abcde f"
Parameters="Brent, 0x30" />
</DockPanel.Resources>
</DockPanel>
Как всегда, имена элементов XAML представляют имена классов Framework. Поэтому элемент ObjectDataSource создает экземпляр класса ObjectDataSource . Значение атрибута def:Name — это имя этого ресурса ("source1" в предыдущем примере).
Экземпляр ObjectDataSource создаст новый экземпляр класса, на который ссылается TypeName , либо путем вызова конструктора по умолчанию, либо при указании атрибута Parameters путем вызова конструктора, который лучше всего соответствует сигнатуре значения атрибута Parameter .
Помните, что разметка эквивалентна коду, поэтому предыдущая разметка совпадает со следующим кодом:
ObjectDataSource source1 = new ObjectDataSource();
source1.TypeName = "MyNamespace.Person, MyAssembly, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=0123456789abcdef";
source1.Parameters = "Brent, 0x30";
Класс ObjectDataSource также предоставляет механизмы для вызова методов для объектов и ссылки на существующие объекты в дополнение к простому создании экземпляра нового объекта.
Использование источника данных с привязкой данных
Источник данных можно объявить как ресурс в свойстве Resources элемента или ресурсах уровня приложения. Любой источник данных, объявленный в ресурсах приложения, можно использовать в приложении на любой странице. Источник данных, определенный в ресурсах элемента, может использоваться только в пределах область элемента.
Источник данных можно объявить как ресурс в свойстве Resources элемента или ресурсах уровня приложения. Любой источник данных, объявленный в ресурсах приложения, можно использовать в приложении на любой странице. Источник данных, определенный в ресурсах элемента, может использоваться только в пределах область элемента.
В приведенном примере привязка данных привязывает источник данных source1. Для атрибута DataSource можно задать идентификатор ресурса XAML. Когда ресурс реализует интерфейс IDataSource , среда выполнения установит в качестве свойства Source экземпляра Bind объект, возвращаемый свойством Data указанного ресурса DataSource . Если ресурс не реализует интерфейс IDataSource , среда выполнения задает свойство Source привязки для самого объекта ресурса.
В предыдущем примере атрибут DataSource ссылается на ресурс ObjectDataSource . Поэтому привязка запрашивает свойство Data из ObjectDataSource. Источник данных, в свою очередь, создает экземпляр класса Person , как указано в разметке.
В первой кнопке свойство Source экземпляра Bind ссылается на этот экземпляр объекта Person . Путь просто Name, поэтому привязка извлекает свойство Name экземпляра Person .
Во второй кнопке DataContext привязывается к ObjectDataSource. Это действие установит в DataContext объекта Button значение Person , чтобы все привязки в Button использовали объект Person в качестве источника по умолчанию для своих привязок.
Аналогичным образом можно привязать данные к любому из доступных источников данных. Некоторые другие источники данных, поставляемые с longhorn, упоминаются в следующих абзацах. Другие, например источники данных для получения данных из веб-служб, будут подключены к сети.
Использование XML в качестве источника данных
Класс XmlDataSource — это источник данных, использующий модель DOM в качестве базового поставщика данных. Вы можете использовать разметку для создания модели DOM на основе URL-адреса, ссылающегося на ПОТОК XML. Вы также можете создать модель DOM, указав XML-код, встроенный в разметку, как показано в следующем примере:
Использование URI
<DockPanel>
<DockPanel.Resources>
<XmlDataSource def:Name="source2"
Source="http://www.wiseowl.com/People.xml"
XPath="/People/Person[@Age>21]" />
Использование встроенной разметки
<XmlDataSource def:Nsme="source3"
XPath="/People/Person[@Age>50]" >
<People>
<Person Name='Bambi' Age='61'>
<Person Name='Bozo' Age='54'>
<Person Name='Brent' Age='48'>
§ </People>
</XmlDataSource>
</DockPanel.Resources>
</DockPanel>
Использование набора данных в качестве источника данных
Класс SqlDataSource — это источник данных, который использует DataSet в качестве базового поставщика данных. Он создает набор данных и заполняет его, выполняя команду SQL в базе данных.
<DockPanel>
<DockPanel.Resources>
<SqlDataSource def:Name="source4">
ConnectionString="server=localhost;Database=UserGroup"
SelectCommand="SELECT * FROM Members" />
</SqlDataSource>
<DockPanel.Resources>
</DockPanel>
Кроме того, можно использовать класс ObjectDataSource и выполнить привязку к строго типизированному классу DataSet, определенному в файле кода программной части.
<DockPanel>
<DockPanel.Resources >
<ObjectDataSource def:Name="sds1"
Type="MyDataset"/>
</ObjectDataSource>
</DockPanel.Resources>
</DockPanel>
Использование хранилища Windows в качестве источника данных
Класс WinFS DataSource использует WinFS в качестве базового поставщика данных. Его можно использовать для привязки к повседневной информации, поддерживаемой хранилищем Microsoft® Windows®.
<DockPanel>
<DockPanel.Resources>
<WinFSDataSource ContextString="c:\">
<WinFSDataSource.Query
Type="Person" Filter="DisplayName='Ted'" Sort="DisplayName ASC">
<Query.ProjectionOptions Field="DisplayName" />
<Query.ProjectionOptions Field="Birthdate">
<Projection.ProjectionOptions … />
</Query.ProjectionOptions>
</ WinFSDataSource.Query>
</WinFSDataSource>
</DockPanel.Resources>
</DockPanel>
Использование пользовательского источника данных
Можно также указать пользовательский класс в качестве источника данных. Класс должен реализовывать интерфейс IDataSource . Как правило, необходимо связать префикс пространства имен XML с пространством имен пользовательского класса, а затем использовать имя класса с префиксом в разметке, как обычно:
<Canvas … >
§
<Canvas.Resources>
<WO:InfraredDataSource def:Name="source8"
PropA='value1'
PropB='value2'
</WO:InfraredDataSource>
</Canvas.Resources>
</Canvas>
Сводка
Привязка данных предоставляет простой и эффективный способ подключения информации к элементу пользовательского интерфейса, отображающего данные. Вы получаете автоматическое распространение значений в любом направлении( один раз или несколько раз) с возможностью преобразования представления данных на лету, когда это необходимо. И это можно сделать практически без программного кода с помощью разметки. Привязка данных позволяет получить нужные данные и перейти к записи остальной части приложения.
Перейдите к главе 6. Общение