Основные привязки

Browse sample. Обзор примера

Привязка данных .NET Multi-platform App UI (.NET MAUI) связывает пару свойств между двумя объектами, хотя бы одним из которых обычно является объект пользовательского интерфейса. Эти два объекта называются целевым объектом и источником:

  • Целевой объект — это объект (и свойство), к которому устанавливается привязка данных.
  • Источник — это объект (и свойство), на который ссылается привязка данных.

В самом простом случае данные поступают от источника к целевому объекту, то есть целевое свойство устанавливается на основе значения свойства источника. Однако в некоторых случаях данные могут поступать от целевого объекта к источнику или перемещаться в обоих направлениях.

Важно!

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

Привязки с контекстом привязки

Рассмотрим следующий пример XAML, намерение которого состоит в повороте:LabelSlider

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicCodeBindingPage"
             Title="Basic Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="48"
               HorizontalOptions="Center"
               VerticalOptions="Center" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Без привязки данных необходимо настроить событие ValueChanged объекта Slider в обработчике событий, который обращается к свойству Value объекта Slider и задает это значение свойству Rotation объекта Label. Привязка данных автоматизирует эту задачу, поэтому обработчик событий и код в нем больше не требуются.

Вы можете задать привязку к экземпляру любого класса, производного от BindableObject, который включает производные Element, VisualElement, View и View. Привязка всегда настраивается в целевом объекте. Привязка ссылается на исходный объект. Чтобы настроить привязку данных, используйте следующие два члена класса цели.

  • Свойство BindingContext задает исходный объект.
  • Метод SetBinding указывает целевое свойство и исходное свойство.

В этом примере Label является целевым объектом привязки, а Slider — источником привязки. Изменения в источнике Slider влияют на угол поворота целевого объекта Label. Данные поступают от источника к целевому объекту.

Метод SetBinding, определенный объектом BindableObject, имеет аргумент типа BindingBase, из которого производится класс Binding, но есть другие методы SetBinding, определенные классом BindableObjectExtensions. Код для XAML использует более SetBinding простой метод расширения из BindableObjectExtensions класса:

public partial class BasicCodeBindingPage : ContentPage
{
    public BasicCodeBindingPage()
    {
        InitializeComponent();

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, "Value");
    }
}

Объект Label является целевым объектом привязки, поэтому на этом объекте устанавливается это свойство и в нем вызывается метод. Свойство BindingContext указывает источник привязки, то есть Slider. Метод SetBinding вызывается в целевом объекте привязки, но указывает свойство целевого объекта и свойство источника. Свойство целевого объекта указывается как объект BindableProperty: Label.RotationProperty. Свойство источника указывается как строка и определяет свойство Value объекта Slider.

Важно!

целевое свойство должно поддерживаться свойством, подходящим для привязки. Поэтому целевой объект должен быть экземпляром класса, наследуемого от BindableObject. Дополнительные сведения см. в разделе "Привязываемые свойства".

Исходное свойство указывается как строка. На внутреннем уровне используется отражение для доступа к фактическому свойству. В данном случае, однако, свойство Value также поддерживается привязываемым свойством.

При изменении свойства объекта Slider объект Label поворачивается соответствующим образом:

Basic code binding.

Кроме того, привязка данных может быть указана в XAML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicXamlBindingPage"
             Title="Basic XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Как и в коде, привязка данных задается в целевом объекте, то есть Label. Для определения привязки данных используются два расширения разметки XAML:

  • Расширение разметки x:Reference требуется для ссылки на исходный объект, то есть Slider с именем slider.
  • Расширения разметки Binding связывает свойство Rotation объекта Label со свойством Value объекта Slider.

Дополнительные сведения о расширениях разметки XAML см. в разделе "Использование расширений разметки XAML".

Примечание.

Исходное свойство указывается со Path свойством Binding расширения разметки, которое соответствует Path свойству Binding класса.

Расширения разметки XAML, такие как x:Reference и Binding, могут иметь определенные атрибуты свойства содержимого. Для расширения разметки XAML это означает, что имя свойства не нужно отображать. Свойство Name является свойством содержимого x:Reference, а свойство Path является свойством содержимого Binding, то есть их можно удалить из выражения:

<Label Text="TEXT"
       FontSize="80"
       HorizontalOptions="Center"
       VerticalOptions="Center"
       BindingContext="{x:Reference slider}"
       Rotation="{Binding Value}" />

Привязки без контекста привязки

Свойство BindingContext является важным компонентом привязок данных, но оно не всегда необходимо. Исходный объект можно указать в вызове SetBinding или Binding расширении разметки:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeCodeBindingPage"
             Title="Alternative Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

В этом примере Slider определяется для управления свойством Scale объекта Label. По этой причине Slider устанавливается диапазон от –2 до 2.

Файл программной части задает привязку с SetBinding методом, а второй аргумент является конструктором для Binding класса:

public partial class AlternativeCodeBindingPage : ContentPage
{
    public AlternativeCodeBindingPage()
    {
        InitializeComponent();

        label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
    }
}

Конструктор Binding имеет 6 параметров, поэтому параметр source указан с именованным аргументом. Аргумент является объектом slider.

Примечание.

Класс VisualElement также определяет свойства ScaleX и ScaleY, которые могут масштабировать VisualElement по-разному в горизонтальном и вертикальном направлениях.

Кроме того, привязка данных может быть указана в XAML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeXamlBindingPage"
             Title="Alternative XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               Scale="{Binding Source={x:Reference slider},
                               Path=Value}" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

В этом примере Binding расширение разметки имеет два набора свойств и SourcePathразделено запятой. Свойство Source задано встроенному расширению разметки x:Reference, которое в противном случае имеет тот же синтаксис, что и параметр BindingContext.

Свойство содержимого расширения разметки Binding — Path, но часть Path= расширения разметки можно исключить только в том случае, если это первое свойство в выражении. Чтобы исключить часть Path=, необходимо поменять два свойства местами:

Scale="{Binding Value, Source={x:Reference slider}}" />

Хотя расширения разметки XAML обычно разделены с помощью фигурных скобок, они также могут быть выражены как элементы объекта:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Source="{x:Reference slider}"
                 Path="Value" />
    </Label.Scale>
</Label>

В этом примере SourcePath свойства являются обычными атрибутами XAML. значения заключены в кавычки и атрибуты не разделяются запятыми. Расширение разметки x:Reference также может стать элементом объекта:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Path="Value">
            <Binding.Source>
                <x:Reference Name="slider" />
            </Binding.Source>
        </Binding>
    </Label.Scale>
</Label>

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

Пока в примерах мы задавали свойство BindingContext и свойство Source класса Binding для расширения разметки x:Reference, чтобы ссылаться на другое представление на странице. Эти два свойства имеют тип Object, и их можно задать для любого объекта, который содержит свойства, подходящие для источников привязки. Можно также задать BindingContext расширение разметки или Source свойство x:Static , чтобы ссылаться на значение статического свойства или поля, или StaticResource расширение разметки для ссылки на объект, хранящийся в словаре ресурсов, или непосредственно к объекту, который часто является экземпляром viewmodel.

Примечание.

Свойство BindingContext также может быть задано для объекта Binding, чтобы свойства Source и Path объекта Binding определяли контекст привязки.

Наследование контекста привязки

Исходный объект можно указать с помощью BindingContext свойства или Source свойства Binding объекта. Если заданы оба свойства, свойство Source объекта Binding имеет приоритет над BindingContext.

Важно!

BindingContext Значение свойства наследуется через визуальное дерево.

В следующем примере XAML демонстрируется наследование контекста привязки:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BindingContextInheritancePage"
             Title="BindingContext Inheritance">
    <StackLayout Padding="10">
        <StackLayout VerticalOptions="Fill"
                     BindingContext="{x:Reference slider}">

            <Label Text="TEXT"
                   FontSize="80"
                   HorizontalOptions="Center"
                   VerticalOptions="End"
                   Rotation="{Binding Value}" />

            <BoxView Color="#800000FF"
                     WidthRequest="180"
                     HeightRequest="40"
                     HorizontalOptions="Center"
                     VerticalOptions="Start"
                     Rotation="{Binding Value}" />
        </StackLayout>

        <Slider x:Name="slider"
                Maximum="360" />
    </StackLayout>
</ContentPage>

В этом примере BindingContext свойство StackLayout объекта задано slider . Этот контекст привязки наследуется объектами Label и BoxView, оба из которых имеют свойства Rotation, зависящие от свойства Value объекта Slider:

Binding context inheritance.