Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Как правило, разработчики объявляют привязки непосредственно в разметке XAML элементов пользовательского интерфейса, к которым они хотят привязать данные. Однако привязки также можно объявить в коде. В этой статье описано, как объявлять привязки как в XAML, так и в коде.
Предпосылки
Важно, чтобы перед прочтением этой статьи вы были знакомы с основными понятиями и принципами использования расширений разметки. Дополнительные сведения о расширениях разметки см. в расширения разметки иWPF XAML.
В этой статье не рассматриваются понятия привязки данных. Описание концепции привязки данных см. в разделе Общие сведения о привязке данных.
Объявление привязки в XAML
Binding — это расширение разметки. При использовании расширения привязки для объявления привязки объявление состоит из ряда предложений после ключевого слова Binding
и разделенных запятыми (,). Пункты в обязательной декларации могут находиться в любом порядке, и существует множество возможных комбинаций. Эти предложения имеют формат имя=значение, где имя — это имя свойства Binding, а значение — это значение, которое устанавливается для этого свойства.
При создании строк объявления привязки в разметке, их необходимо присоединить к конкретному свойству зависимости целевого объекта. В следующем примере показано, как привязать свойство TextBox.Text с помощью расширения привязки, указав свойства Source и Path.
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>
В предыдущем примере используется простой тип объекта данных Person
. Следующий фрагмент кода — это код для этого объекта:
class Person
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
}
Public Class Person
Public Property Name As String
Public Property Birthdate As DateTime
End Class
Большинство свойств класса Binding можно указать таким образом. Дополнительные сведения о расширении привязки, а также список свойств класса Binding, которые невозможно задать с помощью расширения привязки, см. в обзорной статье Привязка расширения разметки (.NET Framework).
Пример создания привязки в XAML см. в статье "Создание привязки данных".
Синтаксис объектных элементов
Синтаксис элемента объекта является альтернативой созданию объявления привязки. В большинстве случаев нет каких-то особых преимуществ в использовании либо расширения разметки, либо синтаксиса объектных элементов. Но когда расширение разметки не подходит конкретно для вашего сценария (например, если значение свойства имеет нестроковый тип, для которого не существует преобразования), то следует использовать синтаксис объектных элементов.
В предыдущем разделе показано, как выполнить привязку к расширению XAML. В следующем примере показано выполнение той же привязки, но используется синтаксис объектных элементов:
<TextBlock>
<TextBlock.Text>
<Binding Source="{StaticResource myDataSource}" Path="Name"/>
</TextBlock.Text>
</TextBlock>
Дополнительные сведения о различных терминах см. в разделе Подробное описание синтаксиса XAML (.NET Framework).
MultiBinding и PriorityBinding
MultiBinding и PriorityBinding не поддерживают синтаксис расширения XAML. Поэтому вы должны использовать синтаксис объектных элементов, если объявляете MultiBinding или PriorityBinding в XAML.
Создание привязки в коде
Задать привязку можно и другим способом, установив значения свойств объекта Binding непосредственно в коде, а затем назначив привязку свойству. В следующем примере показано создание объекта Binding в коде.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Make a new data source object
var personDetails = new Person()
{
Name = "John",
Birthdate = DateTime.Parse("2001-02-03")
};
// New binding object using the path of 'Name' for whatever source object is used
var nameBindingObject = new Binding("Name");
// Configure the binding
nameBindingObject.Mode = BindingMode.OneWay;
nameBindingObject.Source = personDetails;
nameBindingObject.Converter = NameConverter.Instance;
nameBindingObject.ConverterCulture = new CultureInfo("en-US");
// Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
' Make a new data source object
Dim personDetails As New Person() With {
.Name = "John",
.Birthdate = Date.Parse("2001-02-03")
}
' New binding object using the path of 'Name' for whatever source object is used
Dim nameBindingObject As New Binding("Name")
' Configure the binding
nameBindingObject.Mode = BindingMode.OneWay
nameBindingObject.Source = personDetails
nameBindingObject.Converter = NameConverter.Instance
nameBindingObject.ConverterCulture = New CultureInfo("en-US")
' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)
End Sub
Предыдущий код задает для привязки следующее:
- Путь к свойству для объекта источника данных.
- Режим привязки.
- Источник данных, в данном случае это простой экземпляр объекта, представляющий человека.
- Необязательный преобразователь, обрабатывающий значение, поступающее из объекта источника данных, до его назначения целевому свойству.
Если объект, который вы привязываете, является FrameworkElement или FrameworkContentElement, можно вызвать метод SetBinding
непосредственно в объекте, а не использовать BindingOperations.SetBinding. Пример см. в разделе Практическое руководство. Создание привязки в коде.
В предыдущем примере используется простой тип объекта данных Person
. Ниже приведен код для этого объекта:
class Person
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
}
Public Class Person
Public Property Name As String
Public Property Birthdate As DateTime
End Class
Синтаксис пути привязки
Используйте свойство Path, чтобы указать исходное значение, к которому необходимо привязать:
В самом простом случае значение свойства Path — это имя свойства исходного объекта, используемого для привязки, например
Path=PropertyName
.Вложенные свойства можно указать аналогичным синтаксисом, как в C#. Например, предложение
Path=ShoppingCart.Order
задает привязку к подсвойствуOrder
объекта или к свойствуShoppingCart
.Чтобы привязать к присоединенному свойству, поместите скобки вокруг присоединенного свойства. Например, для привязки к присоединенному свойству DockPanel.Dockсинтаксис
Path=(DockPanel.Dock)
.Индексаторы свойства можно указать в квадратных скобках после имени свойства, в котором применяется индексатор. Например, оператор
Path=ShoppingCart[0]
устанавливает привязку к индексу, который соответствует тому, как механизм внутреннего индексирования вашего свойства обрабатывает строку "0". Также поддерживаются вложенные индексаторы.Индексаторы и подсвойства могут быть смешаны в разделе
Path
; например,Path=ShoppingCart.ShippingInfo[MailingAddress,Street].
Индексаторы могут иметь несколько внутренних параметров, разделенных запятыми (
,
). Тип каждого параметра можно указать с скобками. Например, у вас может бытьPath="[(sys:Int32)42,(sys:Int32)24]"
, гдеsys
сопоставляется с пространством именSystem
.Если источником является представление коллекции, текущий элемент можно указать с косой чертой (
/
). Например, условиеPath=/
устанавливает связывание с текущим элементом представления. Если источник является коллекцией, этот синтаксис указывает текущий элемент представления коллекции по умолчанию.Имена свойств и косая черта можно объединить для обхода свойств, которые являются коллекциями. Например,
Path=/Offices/ManagerName
указывает текущий элемент исходной коллекции, который содержит свойствоOffices
, которое также является коллекцией. Его текущий элемент — это объект, содержащий свойствоManagerName
.При необходимости для привязки к текущему источнику можно использовать путь в виде точки (
.
). Например,Text="{Binding}"
эквивалентенText="{Binding Path=.}"
.
Механизм экранирования
Внутри индексаторов (
[ ]
) знак крышки (^
) задает экранирование следующего символа.Если вы задаете Path в XAML, необходимо также экранировать (с помощью сущностей XML) определенные символы, которые являются особыми для определения языка XML:
Используйте
&
для экранирования символа&
.Используйте
>
для экранирования конечного тега>
.
Кроме того, если вы задаете всю привязку в атрибуте, используя синтаксис расширения разметки, необходимо экранировать (с помощью обратной косой черты
\
) символы, которые являются специфическими для синтаксического анализатора расширения разметки WPF:Обратная косая черта (
\
) сама по себе является escape-символом.Знак равенства (
=
) разделяет имя и значение свойства.Запятая (
,
) разделяет свойства.Закрывающая фигурная скобка (
}
) — это конец расширения разметки.
Направление привязки
Используйте свойство Binding.Mode для указания направления привязки. Ниже перечислены доступные режимы для обновлений привязки:
Режим привязки | Описание |
---|---|
BindingMode.TwoWay | Обновляет целевое свойство или свойство источника при изменении целевого свойства или свойства источника. |
BindingMode.OneWay | Обновляет целевое свойство только при изменении свойства источника. |
BindingMode.OneTime | Обновляет целевое свойство только при запуске приложения или при изменении DataContext. |
BindingMode.OneWayToSource | Обновляет исходное свойство при изменении целевого свойства. |
BindingMode.Default | Вызывает использование значения по умолчанию Mode целевого свойства. |
Дополнительные сведения см. в перечислении BindingMode.
В следующем примере показано, как задать свойство Mode:
<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />
Чтобы обнаружить изменения источника (применимо к привязкам OneWay и TwoWay), источник должен реализовать подходящий механизм уведомления об изменении свойств, например INotifyPropertyChanged. Дополнительные сведения см. в статье Предоставление уведомлений об изменениях.
Для привязок TwoWay или OneWayToSource можно управлять временем обновления источника, задав свойство UpdateSourceTrigger. Дополнительные сведения см. в разделе UpdateSourceTrigger.
Поведение по умолчанию
Поведение по умолчанию выглядит следующим образом, если не указано в объявлении:
Создается преобразователь по умолчанию, который пытается выполнить преобразование типов между исходным значением привязки и целевым значением привязки. Если преобразование невозможно сделать, преобразователь по умолчанию возвращает
null
.Если вы не задаете ConverterCulture, подсистема привязки использует свойство
Language
целевого объекта привязки. В языке XAML это свойство по умолчанию имеет значениеen-US
или наследует свое значение от корневого элемента (или любого элемента) страницы, если оно было задано явным образом.При условии, что привязка уже имеет контекст данных (например, контекст данных, наследуемый от родительского элемента), а элемент или коллекция, возвращаемые этим контекстом, подходят для привязки без необходимости дополнительного изменения пути, объявление привязки может вообще не иметь предложений:
{Binding}
. Таким способом привязка часто задается для стилей данных, где привязка воздействует на коллекцию. Дополнительные сведения см. в разделе Использование всего объекта в качестве источника привязки.Значение по умолчанию Mode варьируется между односторонней и двухсторонней привязкой в зависимости от привязанного свойства зависимости. Вы всегда можете явно объявить режим привязки, чтобы убедиться, что ваша привязка имеет требуемое поведение. В целом свойства доступных для редактирования пользователями элементов управления, таких как TextBox.Text и RangeBase.Value, по умолчанию имеют двухсторонние привязки, в то время как большинство других свойств по умолчанию имеет односторонние привязки.
Значение по умолчанию UpdateSourceTrigger изменяется в диапазоне от PropertyChanged до LostFocus также в зависимости от привязанного свойства зависимости. Значение по умолчанию для большинства свойств зависимостей — PropertyChanged, а свойство TextBox.Text имеет значение по умолчанию LostFocus.
См. также
- Обзор привязки данных
- Обзор источников привязки
- Создание привязки данных
- Синтаксис PropertyPath в XAML (.NET Framework)
.NET Desktop feedback