Привязка в .NET MAUI. Основы привязки

Обычно, в любом приложении, будь то приложение .NET MAUI, Blazor или любое другое приложение, можно выделить, как минимум, две части — это интерфейс пользователя, используя который, пользователь взаимодействует с приложением (frontend) и часть, в которой происходит сбор, обработка и хранение данных (backend). Одна из задач, которая стоит перед разработчиком приложения состоит в том, чтобы организовать взаимодействие этих частей — когда пользователь вводит какие-либо данные, то эти данные должны быть каким-либо образом использованы приложением и наоборот — если приложение производит какие-либо изменения в данных, то эти данные должны отобразиться в интерфейсе пользователя. Одним из распространенных решений этой задачи является использование событий: один объект сообщает посредствам событий об изменениях, другой (или другие объекты) — производит какую-либо работу по обработке этих изменений. Однако, наличие большого количества разнообразных объектов приводит к такому же разнообразию обработчиков событий в приложении и, как следствие, код приложения становится трудночитаемым и поддерживаемым, содержит большой объем однотипного стандартного кода. Механизм привязки позволяет автоматизировать процесс передачи данных от одного объекта к другому.

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

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

Эти два объекта называются целевым объектом (source) и источником (target):

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

Целевым объектом обычно выступает како-либо элемент управления (кнопка, метка, текстовое поле и т.д.), производный от BindableObject. Что касается источника привязки, то таким объектом может выступать как объект, производный от BindableObject, так и, в принципе, объект любого класса.

Привязка всегда настраивается в целевом объекте и указывает на исходный объект.

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

Чтобы настроить привязку данных в коде C#, в .NET MAUI используются следующие два члена класса цели:

  • Свойство BindingContext, которое задает объект-источник.
  • Метод SetBinding(), который указывает два связываемых свойства: целевое и исходное.

Рассмотрим простой пример создания привязки данных в .NET MAUI. Создайте новое приложение .NET MAUI и измените файл MainPage.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="MauiApp11.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">

            <Entry x:Name="textEdit"/>
            <Label x:Name="textLabel"></Label>

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

Пусть наша задача будет состоять в том, чтобы при вводе текста в Entry этот текст отображался в Label. Если НЕ использовать привязку, то такую задачу можно решить с использованием события TextChanged у элемента Entry. Создадим новый обработчик события в файле отдельного кода:

namespace MauiApp11
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            
        }

        //обработчик события TextChanged
        private void textEdit_TextChanged(object sender, TextChangedEventArgs e)
        {
            textLabel.Text = e.NewTextValue;
        }
    }
}

и назначим этот обработчик событию Entry:

<Entry x:Name="textEdit" TextChanged="textEdit_TextChanged"/>

Теперь можно запустить приложение и проверить его работу:Теперь изменим немного код и воспользуемся привязкой. Для этого, во-первых, удалим обработчик события TextChanged и изменим XAML-код элемента на предыдущий, то есть на:

<Entry x:Name="textEdit"/>

и, во-вторых, изменим конструктор класса MainPage следующим образом:

public MainPage()
{
    InitializeComponent();
    textLabel.BindingContext = textEdit;
    textLabel.SetBinding(Label.TextProperty, "Text");
}

Здесь целевым объектом выступает метка, а источником — текстовое поле, поэтому свойство BindingContext мы устанавливаем именно у метки:

textLabel.BindingContext = textEdit;

Далее мы вызываем метод SetBinding(), чтобы установить привязку. Здесь обратите внимание на первый параметр метода — Label.TextProperty. Дело в том, что для установления привязки мы должны указать свойство типа BindableProperty, которым и является TextProperty, а не обычно используемое свойство Text. Более того, свойство TextProperty статическое,

public static readonly BindableProperty TextProperty;

поэтому мы указываем его, используя класс элемента

textLabel.SetBinding(Label.TextProperty, "Text");

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

Привязка в XAML

Совсем не обязательно использовать код C# для привязки. В 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="MauiApp11.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">

            <Entry x:Name="textEdit"/>
            <Label x:Name="textLabel"
                   BindingContext="{x:Reference textEdit}"
                   Text="{Binding Text}"></Label>

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

При этом код класса MainPage можно сократить до следующего:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}

При указании свойства BindingContext у Label мы воспользовались расширением разметки x:Reference, чтобы передать ссылку на текстовое поле textEdit. Что касается свойства Text метки, то здесь мы также воспользовались расширением разметки Binding указав в качестве параметра свойство объекта-источника Text. То есть, фактически, мы произвели те же самые действия в XAML, что и ранее в коде C# — определили контекст привязки и установили привязку к свойству Text.

Расширения x:Reference и Binding могут содержать различные параметры. Например, во всех представленных выше примерах мы использовали важное для привязки свойство элемента — BindingContext. Однако, мы можем не указывать это свойство явно в коде. Вместо этого мы можем воспользоваться параметром Source расширения Binding и сделать код XAML для метки следующим:

<Label x:Name="textLabel"
       Text="{Binding Source={x:Reference textEdit}, Path=Text}"></Label>

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

Расширение разметки Binding имеет свои преимущества, по сравнению с определением привязки в коде. Например, мы можем привязать различные свойства Label к свойствам различных объектов. Например, изменим код 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="MauiApp11.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">

            <Slider Maximum="90" Minimum="-90" x:Name="Rotator"/>

            <Entry x:Name="textEdit"/>
            <Label x:Name="textLabel"
                   Text="{Binding Source={x:Reference textEdit}, Path=Text}"
                   Rotation="{Binding Source={x:Reference Rotator}, Path=Value}"/>

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

Здесь мы привязываем свойство Text метки к свойству Text поля ввода, а свойство Rotation — к свойству Value объекта Rotator типа Slider. Теперь можно запустить приложение, ввести какой-нибудь текст в поле ввода и изменить значение Slider, чтобы метка начала поворачиваться:

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

Итого

Привязка — это метод связывания свойств двух объектов таким образом, чтобы изменения в свойстве одного объекта автоматически отражались свойстве другого объекта. Привязку можно осуществлять как в коде C#, так и в коде XAML, используя для этого расширения разметки. Расширение разметки Binding имеет свои преимущества — так, используя Binding в XAML мы можем привязывать разные свойства объекта-цели к свойствам нескольких объектов-источников.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии