Общие сведения об объявлении привязок

В этом разделе описываются различные способы объявления привязок.

Необходимые компоненты

Важно, чтобы перед прочтением этого раздела вы были знакомы с основными понятиями и принципами использования расширений разметки. Подробнее о расширениях разметки см. в разделе Расширения разметки и XAML WPF.

В этом разделе не рассматриваются сведения о привязке данных. Описание концепции привязки данных см. в разделе Общие сведения о привязке данных.

Объявление привязки в XAML

В этом разделе описывается объявление привязки в XAML.

Использование расширения разметки

Binding является расширением разметки. Если для объявления привязки вы используете расширение привязки, то объявление состоит из ряда предложений, следующих за ключевым словом Binding и разделенных запятыми (,). Предложения в объявлении привязки могут следовать в любом порядке, и существует множество различных комбинаций. Эти предложения имеют формат имя=значение, где имя — это имя свойства Binding, а значение — это значение, которое устанавливается для этого свойства.

При создании строк объявления привязки в разметке они должны быть присоединены к конкретному свойству зависимостей целевого объекта. В следующем примере показано, как привязать свойство TextBox.Text с помощью расширения привязки, указав свойства Source и Path.

<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=PersonName}"/>

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

Синтаксис объектных элементов

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

Ниже приведен пример использования синтаксиса объектных элементов и расширения разметки:

<TextBlock Name="myconvertedtext"
  Foreground="{Binding Path=TheDate,
                       Converter={StaticResource MyConverterReference}}">
  <TextBlock.Text>
    <Binding Path="TheDate"
             Converter="{StaticResource MyConverterReference}"/>
  </TextBlock.Text>
</TextBlock>

В примере показана привязка свойства Foreground путем объявления привязки с использованием синтаксиса расширения. Объявление привязки для свойства Text использует синтаксис объектных элементов.

Дополнительные сведения о различных терминах см. в разделе Подробное описание синтаксиса XAML.

Классы MultiBinding и PriorityBinding

MultiBinding и PriorityBinding не поддерживают синтаксис расширения XAML. Поэтому вы должны использовать синтаксис объектных элементов, если вы объявляете MultiBinding или PriorityBinding в XAML.

Создание привязки в коде

Задать привязку можно и другим способом, — установив значения свойств объекта Binding непосредственно в коде. В следующем примере показано, как создать объект Binding и задать его свойства в коде. В этом примере TheConverter представляет собой объект, реализующий интерфейс IValueConverter.

private void OnPageLoaded(object sender, EventArgs e)
{
    // Make a new source, to grab a new timestamp
    MyData myChangedData = new MyData();

    // Create a new binding
    // TheDate is a property of type DateTime on MyData class
    Binding myNewBindDef = new Binding("TheDate");

    myNewBindDef.Mode = BindingMode.OneWay;
    myNewBindDef.Source = myChangedData;
    myNewBindDef.Converter = TheConverter;
    myNewBindDef.ConverterCulture = new CultureInfo("en-US");

      // myDatetext is a TextBlock object that is the binding target object
    BindingOperations.SetBinding(myDateText, TextBlock.TextProperty, myNewBindDef);
    BindingOperations.SetBinding(myDateText, TextBlock.ForegroundProperty, myNewBindDef);

    lbChooseCulture.SelectedIndex = 0;
}
 Private Sub OnPageLoaded(ByVal sender As Object, ByVal e As EventArgs)
     ' Make a new source, to grab a new timestamp
     Dim myChangedData As New MyData()

     ' Create a new binding
 ' TheDate is a property of type DateTime on MyData class
     Dim myNewBindDef As New Binding("TheDate")

     myNewBindDef.Mode = BindingMode.OneWay
     myNewBindDef.Source = myChangedData
     myNewBindDef.Converter = TheConverter
     myNewBindDef.ConverterCulture = New CultureInfo("en-US")

' myDatetext is a TextBlock object that is the binding target object
     BindingOperations.SetBinding(myDateText, TextBlock.TextProperty, myNewBindDef)
     BindingOperations.SetBinding(myDateText, TextBlock.ForegroundProperty, myNewBindDef)

     lbChooseCulture.SelectedIndex = 0
 End Sub

Если объект, который вы привязываете, является FrameworkElement или FrameworkContentElement, вы можете вызвать метод SetBinding непосредственно в объекте, а не использовать BindingOperations.SetBinding. Пример см. в разделе Создание привязки в коде.

Синтаксис пути привязки

Используйте свойство 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:

    • Используйте &amp; для экранирования символа "&".

    • Используйте &gt; в качестве escape-символа для закрывающего тега «>».

  • Кроме того, если вы задаете всю привязку в атрибуте, используя синтаксис расширения разметки, необходимо экранировать (с помощью обратной косой черты \) символы, которые являются специфическими для синтаксического анализатора расширения разметки WPF:

    • Обратная косая черта (\) сама по себе является escape-символом.

    • Знак равенства (=) разделяет имя свойства и значение этого свойства.

    • Запятая (,) отделяет свойства друг от друга.

    • Закрывающая фигурная скобка (}) указывает конец расширения разметки.

Поведение по умолчанию

Поведение по умолчанию выглядит следующим образом, если не указано в объявлении.

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

  • Если вы не задаете ConverterCulture, подсистема привязки использует свойство Language целевого объекта привязки. В языке XAML это свойство по умолчанию имеет значение "en-US" или наследует свое значение от корневого элемента (или любого элемента) страницы, если оно было задано явным образом.

  • При условии, что привязка уже имеет контекст данных (например, контекст данных, наследуемый от родительского элемента), а объект или коллекция, возвращаемые этим контекстом, подходят для привязки без необходимости дополнительного изменения пути, объявление привязки может вообще не иметь предложений: {Binding}. Таким способом привязка часто задается для стилей данных, где привязка воздействует на коллекцию. Дополнительные сведения см. в подразделе "Использование всего объекта в качестве источника привязки" раздела Общие сведения об источниках привязки.

  • По умолчанию Mode может быть как односторонним, так и двусторонним, в соответствии со свойством зависимостей, для которого осуществляется привязка. Режим привязки всегда можно объявить явным образом, чтобы обеспечить требуемое поведение привязки. В целом свойства доступных для редактирования пользователями элементов управления, таких как TextBox.Text и RangeBase.Value, по умолчанию имеют двусторонние привязки, в то время как большинство других свойств по умолчанию имеет односторонние привязки.

  • Значение по умолчанию UpdateSourceTrigger может быть равно PropertyChanged или LostFocus, что также определяется привязанным свойством зависимостей. Значение по умолчанию для большинства свойств зависимостей — PropertyChanged, а свойство TextBox.Text имеет значение по умолчанию LostFocus.

См. также