Режим привязки определяет в какую сторону будет работать привязка. Все возможные режимы задаются с помощью значений из перечисления BindingMode:
Default
: значение по умолчанию. Для разных элементов и свойств может отличаться
OneWay
: при изменении в источнике изменяется цель (от источника к цели)
OneTime
: привязка установливается только однократно и больше не действует. То есть
цель привязки получает начальное значение из источника привязки. Но при дальнейшем изменении в источнике привязка больше не действует
OneWayToSource
: при изменении в объекте-цели привязки изменяется объект-источник (то есть обратная привязка от цели к источнику)
TwoWay
: изменения в источнике воздействуют на цель привязки, а изменении в цели воздействуют на источник (то есть двусторонняя привязка)
По умолчанию стандартным значением для всех элементов и их свойств является значение OneWay
, то есть односторонняя привязка от источника к цели.
Однако ряд элементов и их свойств по умолчанию используют двустороннюю привязку:
Свойство Date элемента DatePicker
Свойство Text элементов Editor
, Entry
, SearchBar
, и EntryCell
Свойство IsRefreshing элемента ListView
Свойство SelectedItem элемента MultiPage
Свойства SelectedIndex и SelectedItem элемента Picker
Свойство Value элементов Slider
и Stepper
Свойство IsToggled элементов Switch
Свойство On элемента SwitchCell
Свойство Time элемента TimePicker
Режим привязки по умолчанию в каждом свойстве BindingProperty хранится в свойстве DefaultBindingMode, например, получим режим привязки по умолчанию для текста элемента Label:
BindingMode labelTextBindingMode = Label.TextColorProperty.DefaultBindingMode;
Все типы привязки относительно просты и понятны. Поэтому рассмотрим только применение двусторонней привязки
Например, пусть у нас будет два текстовых поля Entry, которые связаны двусторонней привязкой. Для примера определим следуюшую страницу:
namespace HelloApp { class StartPage : ContentPage { public StartPage() { Entry entry1 = new Entry { Margin = 10 }; Entry entry2 = new Entry { Margin = 10 }; entry2.BindingContext= entry1; entry2.SetBinding(Entry.TextProperty, "Text", BindingMode.TwoWay); StackLayout stackLayout = new StackLayout() { Children = { entry1, entry2}, Padding = 10 }; Content = stackLayout; } } }
Здесь для поля entry2 в качестве контекста привязки (BindingContext) выступает другое текстовое поле - entry1. Свойство Text у entry2 привязано к свойству Text элемента
entry1. В качестве третьего параметра в метод element.SetBinding()
передается значение BindingMode
(в данном случае ). Стоит отметить,
что поскольку для свойства Text по умолчанию действует двусторонняя привязка, то мы можем не указывать явным образом режим привязки:
entry2.SetBinding(Entry.TextProperty, "Text");
В итоге при вводе текста в один из текстовых полей автоматически будет изменяться и текст в другом поле.
Если для установки привязки применяется объект Binding, то мы можем задать режим привязки через свойство Mode:
namespace HelloApp { class StartPage : ContentPage { public StartPage() { Entry entry1 = new Entry { Margin = 10 }; Entry entry2 = new Entry { Margin = 10 }; // определяем объект привязки: Source - источник, Path - его свойство, Mode - режим привязки Binding binding = new Binding { Source = entry1, Path = "Text", Mode = BindingMode.TwoWay }; entry2.SetBinding(Entry.TextProperty, binding); StackLayout stackLayout = new StackLayout() { Children = { entry1, entry2}, Padding = 10 }; Content = stackLayout; } } }
Результат будет тот же самый, что и в предыдущем примере.
Установка режима привязки в 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="10"> <Entry x:Name="entry1" Margin="10"/> <Entry x:Name="entry2" Margin="10" BindingContext="{x:Reference entry1}" Text="{Binding Path=Text, Mode=TwoWay}"/> </StackLayout> </ContentPage>
Для установки режима привязки у расширения Binding применяется свойство Mode
, которое принимает одну из констант BindingMode:
Text="{Binding Path=Text, Mode=TwoWay}"/>
Аналогичный пример без BindingContext:
<?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="10"> <Entry x:Name="entry1" Margin="10"/> <Entry x:Name="entry2" Margin="10" Text="{Binding Source={x:Reference Name=entry1}, Path=Text, Mode=TwoWay}"/> </StackLayout> </ContentPage>
Но опять же, поскольку двусторонняя привязка для свойства Text элемента Entry действует по умолчанию, то нам не надо ее устанавливаеть явным образом. Тем не менее если вдруг мы хотим переопределить это поведение по умолчанию, то тогда как раз можно явным образом указать режим привязки. Однако надо учитывать, что не всегда режим привязки работает должным образом, например:
<?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="10"> <Entry x:Name="entry1" Margin="10"/> <Entry x:Name="entry2" Margin="10" Text="{Binding Source={x:Reference Name=entry1}, Path=Text, Mode=OneWay}"/> </StackLayout> </ContentPage>