Привязка

Введение в привязку. BindingContext и объект Binding

Последнее обновление: 15.12.2022

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

Привязка данных состоит из двух компонентов:

  • источник привязки (source) - кто привязывается

  • цель привязки (target) - к кому идет привязка

Привязка осуществляется от свойства источника к свойству цели. И когда происходит изменение источника, механизм привязки автоматически обновляет также и цель.

Схема привязки данных в .NET MAUI и C#

Объект-цель привязки должен представлять объект BindableObject, а свойство, к которому осуществляется привязка, должно быть свойством BindableProperty. Поскольку большинство визуальных элементов в .NET MAUI и C# наследуются от класса BindableObject, то в качестве цели привязки будут, как правило, выступать визуальные элементы.

А вот источником привязки может выступать любой объект языка C#. Однако, надо понимать, что цель привязки должна автоматически изменяться при изменении источника, поэтому нам нужно извещать систему о изменении свойств источника привязки. В .NET MAUI, да и вообще на платформе .NET, в качестве подобного механизма извещения выступает интерфейс INotifyPropertyChanged. То есть нужно реализовать данный интерфейс в объекте-источнике.

Объект BindableObject как раз реализует INotifyPropertyChanged. Поэтому если источником привязки является стандартный визуальный элемент из .NET MAUI, то автоматически будет изменяться и цель привязки. Но если в качестве источника выступает не BindableObject, а какой-нибудь объект простого класса C#, то, как писалось выше, этот класс должен реализовать INotifyPropertyChanged.

Есть два способа установить привязку - с помощью свойства BindingContext и с помощью объекта Binding. Рассмотрим на примерах, как устанавливается привязка в коде C# и в коде XAML.

Свойство BindingContext

Для установки привязки у объекта-цели устанавливается свойство BindingContext. В качестве значения оно принимает источник привязки.

Привязка в коде C#

Для привязки в коде после установки свойства BindingContext у объекта-цели привязки необходимо также вызвать метод SetBinding(), который свяжет свойство объекта-цели со свойством объекта-источника.

namespace HelloApp
{
    class StartPage : ContentPage
    {
        public StartPage()
        {
            Label label = new Label();
            Entry entry = new Entry();

            // Устанавливаем привязку
            // источник привязки - entry, цель привязки - label
            label.BindingContext = entry;
            // Связываем свойства источника и цели
            label.SetBinding(Label.TextProperty, "Text");

            StackLayout stackLayout = new StackLayout
            {
                Children = { label, entry },
                Padding = 20
            };
            Content = stackLayout;
        }
    }
}

Здесь объект-цель привязки - label, а источник привязки - entry. То есть привязка идет от label к entry. Выражение

label.SetBinding(Label.TextProperty, "Text")

устанавливает привязку свойства TextProperty элемента label к свойству Text источника привязки - элемента Entry.

Причем, что важно у объекта цели Label привязка устанавливается именно у свойства BindableProperty, которым является TextProperty, а не просто для свойства Text.

В итоге при вводе данных в текстовое поле будет изменяться значение свойства Text у объекта entry. А это изменение автоматически скажется на объекте label и изменит его свойство TextProperty.

Привязка элементов в приложении .NET MAUI и C#

И таким образом, нам не надо вручную обрабатывать изменения текста в текстовом поле Entry, все за нас делает механизм привязки данных.

Привязка в XAML

Аналогично можно установить привязку и в xaml-коде.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">

    <StackLayout Padding="20">
        <Label BindingContext="{x:Reference entryBox}" Text="{Binding Text}" />
        <Entry x:Name="entryBox" />
    </StackLayout>

</ContentPage>

В XAML действует тот же принцип. Для установки привязки для объекта цели задается свойство BindingContext. Но теперь его значение имеет другую форму: {x:Reference entryBox} - расширению разметки x:Reference передается имя элемента источника. То есть в данном случае источником выступает объект с именем entryBox.

Далее устанавливается сама привязка к свойству:

Text="{Binding Text}"

Здесь также устанавливается привязка к свойству Text. Выражение привязки заключается в фигурные скобки и состоит из слова Binding, после которого указывается свойство источника-привязки. То есть свойство Text объекта label привязано к свойству Text объекта entryBox.

Объект Binding

Другой способ привязки представляет объект Binding. Например:

class StartPage : ContentPage
{
    public StartPage()
    {
        Label label = new Label();
        Entry entry = new Entry();

        // определяем объект привязки: Source - источник, Path - его свойство
        Binding binding = new Binding { Source = entry, Path = "Text" };
        // установка привязки для свойства TextProperty
        label.SetBinding(Label.TextProperty, binding);

        StackLayout stackLayout = new StackLayout()
        {
            Children = { entry, label},
            Padding = 20
        };
        Content = stackLayout;
    }
}

Здесь у объекта Binding настраиваются ряд свойств. В частности, свойство Source указывает на источник привязки, а свойство Path - на свойство источника. В данном случае источником служит объект Entry, а свойством - его свойство Text.

Далее в метод SetBinding() в качестве второго параметра передается объект Binding, инкапсулирующий все опции привязки.

В итоге мы получаем то же самое, что и в прошлой теме: свойство Text объекта Label привязано к свойству Text объекта Entry.

Объект Binding и привязка к свойствам в .net maui и c#

Тоже самое можно прописать и в XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <StackLayout Padding="20">
        <Label x:Name="label" Text="{Binding Source={x:Reference entry}, Path=Text}" />
        <Entry x:Name="entry" />
    </StackLayout>
</ContentPage>

Таким образом, нам необязательно использовать свойство BindingContext для установки привязки к источнику. Более того использование объекта Binding имеет свои преимущества. В частности, с помощью BindingContext мы можем установить только один источник привязки для какого-либо элемента. Но что если мы хотим, чтобы одно свойство у Label было привязано к одному элемену, другое свойство - к другому элементу? В этом случае можно использовать только вышеописанный способ.

Также мы можем одновременно устанавливать и BindingContext, и использовать объект Binding для определения опций привязки, и в этом случае объект Binding будет переопределять BindingContext, если, к примеру, в BindingContext указан один источник привязки, а в объекте Binding другой.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850