Поделиться через


Расширение разметки {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 папке с такими именами, как (для C#). <view name>.g.cs

Подсказка

{x:Bind} имеет стандартный режим OneTime, в отличие от {Binding}, который имеет режим OneWay по умолчанию. Это было выбрано по соображениям производительности, так как использование OneWay приводит к созданию большего объема кода для подключения и обработки обнаружения изменений. Можно четко указать режим для использования однонаправленной (OneWay) или двунаправленной (TwoWay) привязки. Можно также использовать x:DefaultBindMode для изменения режима по умолчанию для {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=value[, propName=value]* Одно или несколько свойств привязки, указанных с помощью синтаксиса пары "имя-значение".
propName Строковое имя свойства, заданного для объекта привязки. Например, "Преобразователь".
value Значение, которое необходимо установить для свойства. Синтаксис аргумента зависит от заданного свойства. Ниже приведен пример использования 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 задает путь для выражения {x:Bind} . Путь — это путь к свойству, указывающий значение свойства, подсвойства, поля или метода, к которому вы привязываетесь (источник). Вы можете явно указать имя свойства 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 в рамках выражения привязки. Вместо этого можно использовать имя элемента в качестве первой части пути для привязки, так как именованные элементы становятся полями на странице или пользовательском элементе управления, представляющем корневой источник привязки.

Collections

Если источник данных является коллекцией, путь к свойству может указывать элементы в коллекции по их позиции или индексу. Например, "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}" — это словарь объектов, поэтому его необходимо привести к data:SampleDataGroup. Обратите внимание на использование пространства имен xml: как префикса пространства имен для сопоставления типа объекта с пространством имен кода, которое не является частью пространства имен 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} для этого объекта в словаре ресурсов.
КонвертерЯзыка Указывает культуру, используемую преобразователем. (Если вы задаете ConverterLanguage, то также следует задать Конвертер.) Культура задается как идентификатор на основе стандартов. Дополнительные сведения см. в разделе ConverterLanguage.
ConverterParameter Задает параметр преобразователя, который можно использовать в логике конвертера. (Если вы задаете ConverterParameter , то также следует задать конвертер.) Большинство преобразователей используют простую логику, которая получает всю необходимую информацию из переданного значения для преобразования и не требует значения 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 предоставляет встроенный логический преобразователь видимости. Преобразователь сопоставляет true с перечислением Visible и false с Collapsed, чтобы можно было привязать свойство Видимости к булеву значению без создания преобразователя. Обратите внимание, что это не функция привязки функций, только привязка свойств. Чтобы использовать встроенный преобразователь, минимальная целевая версия пакета SDK приложения должна быть 14393 или более поздней. Его нельзя использовать, если приложение предназначено для более ранних версий Windows 10. Дополнительные сведения о целевых версиях см. в разделе "Адаптивный код версии".

Подсказка

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

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

{x:Bind} — это расширение разметки только без способа создания или управления такими привязками программным способом. Дополнительные сведения о расширениях разметки см. в обзоре XAML.