Использование привязок данных в XAML

Завершено

Привязки данных можно объявлять в коде или в XAML с помощью расширений разметки. В этом уроке рассматриваются последние, так как это наиболее распространенный способ создания привязок. Это обусловлено рядом причин. Во-первых, большинство разработчиков рассматривают привязки как часть кода пользовательского интерфейса, так как привязки получают данные для отображения в пользовательском интерфейсе. Во-вторых, существует расширение разметки с именем Binding, которое упрощает эту задачу.

Что такое привязки данных

Объект binding связывает два свойства. Одно свойство находится в пользовательском интерфейсе, а другое — в объекте модели данных. При изменении значения любого из этих свойств объект привязки может обновлять другое свойство. Другими словами, привязки — это промежуточные объекты, которые синхронизируют ваши данные и пользовательский интерфейс. Мы используем источник терминов и целевой объект для идентификации двух связанных объектов:

  • Источник: источник может быть объектом любого типа. На практике обычно в качестве источника используется объект данных. Для участия в привязке вам нужно определить свойство для этого исходного объекта. Чтобы определить свойство, задав Path свойство в привязке.

  • Целевой объект: целевой объект — это свойство, которое реализуется с помощью специального свойства, называемого a BindableProperty. Объект, наследуемый BindableProperty от BindableObjectобъекта. Все элементы управления, предоставляемые в .NET MAUI, являются производными от BindableObject и большинство их свойств BindableProperties.

На следующей схеме показано, как привязка является промежуточным объектом между двумя свойствами:

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

Создание привязки данных в XAML

Рассмотрим простую привязку, созданную в XAML, с помощью {Binding} расширения разметки. Эта привязка связывает свойство WeatherService.Humidity исходного объекта со свойством Text элемента управления интерфейса.

<VerticalStackLayout Margin="10">
    <VerticalStackLayout.Resources>
        <ResourceDictionary>
            <services:WeatherService x:Key="myWeatherService" />
        </ResourceDictionary>
    </VerticalStackLayout.Resources>

    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>

Источник привязки:

  • Экземпляр WeatherService объекта типа. Экземпляр ссылается на {StaticResource ...} расширение XAML, указывающее на объект в словаре ресурсов макета стека.

  • Указывает Path на свойство с именем Humidity WeatherService типа.

    Это Path первый неименованный параметр синтаксиса {Binding} , а Path= синтаксис может быть опущен. Эти две привязки эквивалентны:

    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
    <Label Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
    

Целевой объект привязки:

  • Элемент Label управления.
  • Свойство элемента управления Text .

При отображении {Binding} пользовательского интерфейса расширение XAML создает привязку между WeatherService и Label. Привязка считывает WeatherService.Humidity значение свойства в Label.Text свойство.

Использование другого элемента управления в качестве источника привязки

Одной из полезных функций привязки является возможность привязки к другим элементам управления. Следующий КОД XAML является простой демонстрацией:

<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
    <Label x:Name="TargetLabel" Text="TEXT TO ROTATE" BackgroundColor="Yellow" />
    <Slider WidthRequest="100" Maximum="360"
            Value="{Binding Rotation, Mode=OneWayToSource, Source={x:Reference TargetLabel}}" />
</VerticalStackLayout>

Свойство Slider.Value привязано к Label.Rotation свойству, но по-другому, чем ранее. Это свойство использует режим OneWayToSourceпривязки, который изменяет типичный механизм привязки. Вместо исходного обновления целевого объекта OneWayToSourceобновляет источник при изменении целевого объекта. В этом примере при перемещении ползунка обновляется поворот метки на основе значения ползунка, как показано в следующей анимации:

Анимированное изображение элемента управления ползунка, перетаскиваемого с помощью мыши. По мере перемещения ползунка кусок текста поворачивается в соответствии с положением ползунка.

Типичный сценарий для элементов управления привязкой друг к другу заключается в том, что элемент управления, как правило, элемент управления коллекции, такой как или ListView CarouselView, имеет выбранный элемент, который вы хотите использовать в качестве источника данных. В примере страницы, отображающей прогноз погоды, может появиться ListView пятидневный прогноз. Когда пользователь выбирает день в списке, сведения о прогнозе погоды отображаются в других элементах управления. Если пользователь выбирает еще один день, другие элементы управления снова обновляются с помощью сведений о выбранном дне.

Использование одного источника в нескольких привязках

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

<VerticalStackLayout Margin="10">
    <VerticalStackLayout.Resources>
        <vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
    </VerticalStackLayout.Resources>
    <Entry Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>

Вам не нужно использовать то же самое при использовании одного и того же Path Source:

<VerticalStackLayout Margin="10">
    <VerticalStackLayout.Resources>
        <vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
    </VerticalStackLayout.Resources>
    <Entry Text="{Binding Temperature, Source={StaticResource myWeatherService}}" />
    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>

Редко вы представляете один фрагмент данных из источника, хотя это может произойти. Обычно у вас есть несколько элементов управления, использующих различные фрагменты данных из одного источника. Такая ситуация распространена, что BindableObject класс имеет свойство с именем BindingContext , которое работает в качестве источника для привязки данных. Помните, что элементы управления .NET MAUI наследуются от BindableObject класса, поэтому элементы управления MAUI .NET имеют BindingContext свойство.

Source Настройка привязки является необязательным. Привязка, которая не Source задана, автоматически выполняет поиск визуального дерева XAML для BindingContextобъекта, который устанавливается в XAML или назначается родительскому элементу по коду. Привязки оцениваются следующим образом:

  1. Если привязка Sourceопределяет , используется этот источник и останавливается поиск. Привязка Path применяется к Source значению для получения значения. Если Source параметр не задан, поиск начинается для источника привязки.

  2. Поиск начинается с самого целевого объекта. Если целевой объект BindingContext не имеет значения NULL, поиск останавливается и привязка Path применяется к BindingContext значению. BindingContext Если значение равно null, поиск продолжается.

  3. Этот процесс продолжается до тех пор, пока он не достигнет корневого каталога XAML. Поиск заканчивается путем проверки BindingContext корневого каталога для ненулевого значения. Если не найдено допустимого BindingContext , привязка не имеет ничего, чтобы привязаться к ней и ничего не делает.

Обычно для установки BindingContext на уровне корневого объекта применяется ко всему XAML.

Есть одна последняя удобная функция, которую стоит упомянуть. Привязки отслеживают изменения в ссылке на объект своего источника. Это работает даже для привязок, которые используются BindingContext в качестве источника. Если Source или BindingContext переназначается другому объекту, привязка получает данные из нового источника и обновляет целевой объект.

Проверьте свои знания

1.

Что верно для исходного объекта в привязке .NET MAUI?

2.

Что верно для целевого свойства в привязке .NET MAUI?

3.

Если все привязки в элементах управления нуждаются в Grid одном исходном объекте, что является самой безопасной стратегией установки исходного объекта только один раз?