Расширение разметки {x:Bind}

Примечание . Общие сведения об использовании привязки данных в приложении с {x:Bind} (а также для сравнения между {x:Bind} и {Binding}) см . подробное описание привязки данных.

Расширение разметки {x:Bind} , новое для Windows 10, является альтернативой {Binding}. {x:Bind} выполняется меньше времени и меньше памяти, чем {Binding} и поддерживает лучшую отладку.

Во время компиляции XAML {x:Bind} преобразуется в код, который получает значения из свойства в источнике данных и устанавливает его для свойства, определенного в разметке. Объект привязки можно дополнительно настроить таким образом, чтобы он регистрировал изменения значений свойства источника данных и сам обновлялся на основании этих данных (Mode="OneWay"). Кроме того, его можно настроить, чтобы он отправлял изменения собственного значения назад к свойству источника (Mode="TwoWay").

Как правило, объекты привязки, создаваемые с помощью расширений разметки {x:Bind} и {Binding}, выполняют аналогичные функции. Однако {x:Bind} выполняет специальный код, который генерируется во время компиляции, а {Binding} использует универсальную проверку объектов среды выполнения. В результате привязки {x:Bind} (часто именуемые компилированными привязками) имеют большую производительность, обеспечивают проверку ваших выражений привязки и поддерживают отладку, позволяя задавать точки останова в файлах кода, которые создаются как разделяемый класс для вашей страницы. Эти файлы можно найти в папке obj с такими именами, как <view name>.g.cs (для C#).

Совет

{x:Bind} имеет режим по умолчанию OneTime, в отличие от {Binding} с режимом по умолчанию OneWay. Он был выбран в целях повышения производительности, поскольку при использовании OneWay создается больший объем кода для подключения и обнаружения изменений. Можно явно задать режим, чтобы использовать привязку OneWay или TwoWay. x:DefaultBindMode можно также использовать, чтобы изменить режим по умолчанию для {x:Bind} для определенного сегмента дерева разметки. Выбранный режим применяет любые выражения {x:Bind} к этому элементу и его дочерним элементам, которые явным образом не задают режим в качестве части привязки.

Примеры приложений с расширением разметки {x:Bind}

Использование атрибутов XAML

<object property="{x:Bind}" .../>
-or-
<object property="{x:Bind propertyPath}" .../>
-or-
<object property="{x:Bind bindingProperties}" .../>
-or-
<object property="{x:Bind propertyPath, bindingProperties}" .../>
-or-
<object property="{x:Bind pathToFunction.functionName(functionParameter1, functionParameter2, ...), bindingProperties}" .../>
Срок Description
propertyPath Строка, указывающая путь свойства для привязки. Подробную информацию см. в разделе Путь свойства ниже.
bindingProperties
Значение propName=[, значение propName=]* Одна или несколько привязок свойств, указанных с помощью синтаксиса пары "имя/значение".
propName Имя строки свойства для установки на объекте привязки. Например, Converter.
значение Значение, которое следует задать для свойства. Синтаксис аргумента зависит от задаваемого свойства. Вот пример использования propName=значение, где значение само является расширением разметки: Converter={StaticResource myConverterClass}. Дополнительную информацию см. в разделе Свойства, которые можно задать с помощью расширения разметки {x:Bind} ниже.

Примеры

<Page x:Class="QuizGame.View.HostView" ... >
    <Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
</Page>

В этом примере кода XAML используется {x:Bind} со свойством ListView.ItemTemplate. Обратите внимание на объявление значения x:DataType.

  <DataTemplate x:Key="SimpleItemTemplate" x:DataType="data:SampleDataGroup">
    <StackPanel Orientation="Vertical" Height="50">
      <TextBlock Text="{x:Bind Title}"/>
      <TextBlock Text="{x:Bind Description}"/>
    </StackPanel>
  </DataTemplate>

Путь к свойству

PropertyPath задает значение Path для выражения {x:Bind}. Path — путь к свойству, в котором определено значение свойства, подсвойства, поля или метода, к которому выполняется привязка (источник). Можно упомянуть точное имя свойства Path: {x:Bind Path=...}. Или его можно не указывать: {x:Bind ...}.

Разрешение пути свойства

Расширение разметки {x:Bind} не использует DataContext в качестве источника по умолчанию — оно использует страницу или пользовательский элемент управления. Таким образом оно будет выглядеть в коде программной части вашей страницы или пользовательского элемента управления для свойств, полей и методов. Чтобы предоставить модель представления для расширения разметки {x:Bind}, обычно нужно добавить новые поля или свойства в код программной части для страницы или пользовательского элемента управления. Этапы в пути к свойству разделены точками (.), и вы можете добавить несколько разделителей для прохождения по иерархии. Используйте разделительные точки независимо от языка программирования, используемого для реализации объекта, к которому осуществляется привязка.

Например, на странице: Text="{x:Bind Employee.FirstName}" будет искать участника Employee на странице, а затем участника FirstName в объекте, возвращенном участником Employee. Если бы элемент управления элементами привязывался к свойству, содержащему подчиненных сотрудников, то путем свойства мог бы быть Employee.Dependents, а шаблон элемента управления элементами, отобразил бы элементы в Dependents.

В случае использования языков C++/CX {x:Bind} нельзя привязать к частным полям и свойствам в модели страницы или данных — вам потребуется открытое свойство для выполнения привязки. Контактную зону для привязки необходимо предоставлять в качестве классов/интерфейсов CX, чтобы можно было получить соответствующие метаданные. Атрибут [Bindable] не должен быть нужен.

При использовании x:Bind вам не нужно применять ElementName=xxx как часть выражения привязки. Вместо этого можно использовать имя элемента в качестве первой части пути для привязки, так как именованные элементы становятся полями на странице или пользовательском элементе управления, представляющем корневой источник привязки.

Коллекции

Если источником данных выступает коллекция, то в пути свойства можно указывать элементы коллекции по их позиции или индексу. Например, "Teams[0]. Игроки, где литерал "[]" заключает "0", который запрашивает первый элемент в отсчитываемой от нуля коллекции.

Чтобы воспользоваться индексатором, модели необходимо реализовать IList<T> или IVector<T> в типе свойства, которое подлежит индексации. (Обратите внимание, что IReadOnlyList<T> и IVectorView<T> не поддерживают синтаксис индексатора.) Если тип индексированного свойства поддерживает INotifyCollectionChanged или IObservableVector , а привязка — OneWay или TwoWay, она будет регистрировать и прослушивать уведомления об изменениях в этих интерфейсах. Логика отслеживания изменений обновляется с учетом всех изменений коллекции, даже если эти изменения не влияют на конкретное индексированное значение. Это обусловлено тем, что логика ожидания передачи данных общая для всех экземпляров коллекции.

Если источником данных выступает словарь или карта, то в пути свойства можно указывать элементы коллекции по имени строки. Например <, TextBlock Text="{x:Bind Players['John Smith']}" /> будет искать элемент в словаре с именем "Джон Смит". Имя необходимо заключить в кавычки, которые могут быть как двойными, так и одинарными. Для экранирования кавычек в строках можно использовать символ карет (^). Обычно проще всего использовать альтернативные кавычки из тех, которые используются для атрибута XAML. (Обратите внимание, что IReadOnlyDictionary<T> и IMapView<T> не поддерживают синтаксис индексатора.)

Чтобы использовать индексатор строк, модель должна реализовать строку IDictionary<, T> или строку IMap<, T> в типе свойства, который будет индексирован. Если тип индексированного свойства поддерживает IObservableMap, а привязка относится к типу OneWay или TwoWay, то она будет принимать и регистрировать уведомления об изменениях на этих интерфейсах. Логика отслеживания изменений обновляется с учетом всех изменений коллекции, даже если эти изменения не влияют на конкретное индексированное значение. Это обусловлено тем, что логика ожидания передачи данных общая для всех экземпляров коллекции.

Присоединенные свойства

Чтобы привязать к присоединенным свойствам, необходимо поместить имя класса и свойства в скобки после точки. Например, Text="{x:Bind Button22.(Grid.Row)}". Если свойство не объявлено в пространстве имен Xaml, необходимо префиксировать его с пространством имен XML, которое следует сопоставить с пространством имен кода в голове документа.

Приведение

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

В следующем случае obj является свойством объекта типа, но содержит текстовое поле, что позволяет использовать Text="{x:Bind ((TextBox)obj).Text}" или Text="{x:Bind obj.(TextBox.Text)}".

Поле groups3 в Text="{x:Bind (data:SampleDataGroup)groups3[0]. Title}" — это словарь объектов, поэтому его необходимо привести к данным:SampleDataGroup. Обратите внимание на то, как используется префикс пространства имен XML data: для сопоставления типа объектов с пространством имен кода, не являющимся частью пространства имен XAML по умолчанию.

Примечание. Синтаксис приведения в стиле C#является более гибким, чем синтаксис присоединенного свойства, и является рекомендуемыми синтаксисами.

Без пути приведение

Машинный средство синтаксического анализа привязки не предоставляет ключевое слово для представления this в качестве параметра функции, но поддерживает беспутьное приведение (например, {x:Bind (x:String)}), которое можно использовать в качестве параметра функции. Таким образом, является допустимым способом выполнения того, {x:Bind MethodName((namespace:TypeOfThis))} что концептуально эквивалентно {x:Bind MethodName(this)}.

Пример:

Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}"

<Page
    x:Class="AppSample.MainPage"
    ...
    xmlns:local="using:AppSample">

    <Grid>
        <ListView ItemsSource="{x:Bind Songs}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:SongItem">
                    <TextBlock
                        Margin="12"
                        FontSize="40"
                        Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>
namespace AppSample
{
    public class SongItem
    {
        public string TrackName { get; private set; }
        public string ArtistName { get; private set; }

        public SongItem(string trackName, string artistName)
        {
            ArtistName = artistName;
            TrackName = trackName;
        }
    }

    public sealed partial class MainPage : Page
    {
        public List<SongItem> Songs { get; }
        public MainPage()
        {
            Songs = new List<SongItem>()
            {
                new SongItem("Track 1", "Artist 1"),
                new SongItem("Track 2", "Artist 2"),
                new SongItem("Track 3", "Artist 3")
            };

            this.InitializeComponent();
        }

        public static string GenerateSongTitle(SongItem song)
        {
            return $"{song.TrackName} - {song.ArtistName}";
        }
    }
}

Функции в путях привязки

Начиная с Windows 10 версии 1607 {x: Bind} поддерживает использование функции на конечном этапе шаге пути привязки. Это мощная функция привязки данных, которая позволяет выполнять несколько сценариев в разметке. Дополнительные сведения см . в привязках функций.

Привязка события

Привязка события – это уникальная функция для компилированной привязки. Она позволяет определять обработчик для события с использованием привязки, а не применяется в качестве метода в коде программной части. Например: Click="{x:Bind rootFrame.GoForward}".

В случае работы с событиями метод не должен быть перегружен; он должен соответствовать таким условиям:

  • соответствовать подписи события;
  • или не иметь параметров;
  • или иметь такое же количество параметров типов, которые назначаются из типов параметров событий.

В созданном коде программной части скомпилированная привязка обрабатывает событие и направляет его к методу в модели, анализируя путь выражения привязки при возникновении события. Это означает, что, в отличие от привязок свойства, она не отслеживает изменения в модели.

Дополнительную информацию о синтаксисе строк для пути свойства см. в разделе Синтаксис пути свойства, учитывая отличия {x:Bind}, описанные в данной статье.

Свойства, которые можно задать с помощью расширения разметки {x:Bind}

{x:Bind} демонстрируется с помощью замещающего синтаксиса bindingProperties, поскольку есть несколько свойств, доступных для чтения и записи, которые можно задавать в данном случае использования расширения разметки. Свойства можно задавать в любом порядке с парами propName=value, разделенными запятыми. Обратите внимание, что разрывы строк недопустимы в выражении привязки. Для некоторых свойств требуются типы, не предусматривающие преобразования; им необходимы их собственные расширения разметки, вложенные в {x:Bind}.

Эти свойства работают практически так же, как и свойства класса Binding.

Свойство Description
Путь См. раздел Путь к свойству выше.
Преобразователь Указывает объект преобразователя, вызываемый механизмом привязки. Преобразователь можно задать в коде XAML, но только в случае, если вы ссылаетесь на экземпляр объекта, присвоенный в ссылке на расширение разметки {StaticResource} этому объекту в словаре ресурсов.
КонвертерLanguage Указывает язык и региональные параметры, используемые преобразователем. (Если задано значение ПреобразовательLanguage также следует задать Converter.) Язык и региональные параметры задаются как идентификатор на основе стандартов. Подробнее: ConverterLanguage.
ConverterParameter Указывает параметр преобразователя, который можно использовать в логике преобразователя. (Если задано значение ConverterParameter также следует задать Converter.) Большинство преобразователей используют простую логику, которая получает всю необходимую информацию из переданного значения для преобразования и не требует значения ConverterParameter . Параметр ConverterParameter используется для более расширенных преобразователей, у которых больше одной логики и которым недостаточно информации, переданной в ConverterParameter. Вы также можете написать преобразователь, который использует нестроковые значения, но это используется редко. Подробнее см. в разделе "Примечания" статьи ConverterParameter.
Резервное значение Задает значение, которое отображается, когда не удается разрешить источник или путь.
Режим Задает режим привязки в качестве одной из этих строк: OneTime, OneWay или TwoWay. Значение по умолчанию — OneTime. Обратите внимание, что это поведение отличается от шаблона по умолчанию для привязки {Binding}, которая в большинстве случаев имеет значение OneWay.
TargetNullValue Задает значение, которое отображается, когда значение источника разрешается, но оно явно равно null.
BindBack Определяет функцию, используемую для обратного направления двусторонней привязки.
UpdateSourceTrigger Указывает, когда возвращать изменения в элементе управления модели в привязках TwoWay. Значение по умолчанию для всех свойств, кроме TextBox.Text, — PropertyChanged; TextBox.Text — LostFocus.

Примечание.

Если вы преобразуете разметку {Binding} в {x:Bind}, следует учитывать различия между значениями по умолчанию для свойства Mode. x:DefaultBindMode можно использовать для изменения режима по умолчанию для x: Bind для конкретного сегмента дерева разметки. Выбранный режим будет применять любые выражения x:Bind к этому элементу и его дочерним элементам, которые явным образом не задают режим в качестве части привязки. OneTime отличается более высокой производительностью, чем OneWay, поскольку в результате использования OneWay создается больший объем кода для подключения и обнаружения изменений.

Замечания

Поскольку {x:Bind} использует сформированный код, во время компиляции ему необходима информация о типе, чтобы воспользоваться всеми доступными преимуществами. Это означает, что, не зная заранее тип, вы не сможете выполнить привязку к свойствам. По этой причине невозможно использовать {x:Bind} со свойством DataContext, которое относится к типу Object и может во время выполнения изменяться.

При использовании {x:Bind} с шаблонами данных необходимо указать тип, к которым привязано значение x:DataType , как показано в разделе "Примеры ". Вы также можете задавать тип для интерфейса или базового класса, а затем использовать приведения, если понадобится сформулировать полное выражение.

Скомпилированные привязки зависят от создания кода. Если вы используете {x:Bind} в словаре ресурсов, тогда словарь ресурсов должен иметь класс кода программной части. Пример кода см. в разделе Словари ресурсов с привязкой {x:Bind}.

Страницы и пользовательские элементы управления, содержащие скомпилированные привязки, имеют в сформированном коде свойство "Bindings". Включены следующие методы:

  • Update() — обновляет значения всех скомпилированных привязок. Все односторонние или двухсторонние привязки имеют прослушиватели для отслеживания изменений.
  • Initialize() — Если привязки еще не инициализированы, будет вызван метод Update() для инициализации привязок.
  • StopTracking() — отключает все прослушиватели, созданные для одно- и двухсторонних привязок. Прослушиватели можно инициализировать повторно с помощью метода Update().

Примечание.

Начиная с Windows 10 версии 1607, платформа XAML предоставляет встроенный преобразователь Boolean в Visibility. Преобразователь сопоставляет значение true значению перечисления Visible, а значение false значению Collapsed, поэтому можно осуществить привязку свойства Visibility к Boolean без создания преобразователя. Обратите внимание, что это не особенность привязки функций, а исключительно привязка свойств. Для использования встроенного преобразователя минимальная версия целевого пакета SDK вашего приложения должна быть 14393 или более поздней. Вы не сможете использовать преобразователь, если ваше приложение предназначено для более ранних версий Windows 10. Дополнительные сведения о целевых версиях см. в статье Адаптивный к версии код.

Совет. Если необходимо указать одну фигурную скобку для значения, например в Path или ConverterParameter, перед ней следует использовать обратную косую черту: \{. Также можно включить всю строку, содержащую скобки, которые нужно преобразовать, в дополнительный набор кавычек, например: ConverterParameter='{Mix}'.

Converter, ConverterLanguage и ConverterLanguage связаны с сценарием преобразования значения или типа из источника привязки в тип или значение, совместимые со свойством цели привязки. Более подробную информацию и примеры см. в разделе "Преобразования данных" статьи Подробно о привязке данных.

{x:Bind} является исключительно расширением разметки и не дает возможности создавать или управлять такими привязками программным способом. Подробнее о расширениях разметки см. в разделе Обзор языка XAML.