Триггеры данных (data triggers) позволяют отслеживать изменение данных. Триггер данных может выполнять некоторые действия, когда привязанные данные будут соответствовать определенному условию. В .NET MAUI триггеры данных представлены классом DataTrigger. Для отслеживания данных триггер использует привязку и объект Binding.
Определим простейший триггер данных:
<?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"> <Entry TextColor="Green"> <Entry.Triggers> <DataTrigger TargetType="Entry" Binding="{Binding Source={RelativeSource Self}, Path=Text}" Value="admin"> <Setter Property="TextColor" Value="Red" /> </DataTrigger> </Entry.Triggers> </Entry> </StackLayout> </ContentPage>
В данном случае триггер данных определен для элемента Entry. Как и другие триггеры, триггер данных жобавляется в коллекцию Triggers
, только представдяет тип
DataTrigger
.
У триггера данных в обязательном порядке должно быть установлено свойство TargetType
, которое указывает на тип элемента, к которому применяется триггер.
Также у триггера через свойство Binding задается привязка к отслеживаемым данным. Поскольку здесь отслеживаем свойство Text этого же объекта Entry, то задаем относительную привязку к самому себе:
Binding="{Binding Source={RelativeSource Self}, Path=Text}"
А через свойство Value триггер данных определяется значение, при котором будет срабатывать триггер. То есть в данном случае триггер будет срабатывать, когда свойство Text получит значение "admin". Вся работа триггера заключается в установке свойств объекта Entry. Для этого у триггера в коллекцию Setters добавляются объекты Setter, которые указывают, какое свойство будет изменяться и какое значение оно получит. То есть в данном случае, когда свойство Text получит значение "admin", свойство TextColor получит красный цвет:
<Setter Property="TextColor" Value="Red" />
Триггер данных необязательно отслеживает свойство того же элемента, для которого он объявлен. Например:
<?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="entry" Text="" Margin="10" /> <Button Text="Save" TextColor="#01579B" BackgroundColor="#fff" Margin="10"> <Button.Triggers> <DataTrigger TargetType="Button" Binding="{Binding Source={x:Reference entry}, Path=Text.Length}" Value="0"> <Setter Property="IsEnabled" Value="False" /> <Setter Property="BackgroundColor" Value="LightGray"/> <Setter Property="TextColor" Value="Gray"/> </DataTrigger> </Button.Triggers> </Button> </StackLayout> </ContentPage>
Здесь триггер данных задан для кнопки, но отслеживает свойство Text элемента Entry. Если длина текста в Entry равна 0, то делаем кнопку недоступной и устанавливаем для нее соответствующие цвета для текста и фона.
Аналогичный триггер данных в коде C#:
namespace HelloApp { class StartPage : ContentPage { public StartPage() { Entry entry = new Entry { Text = "", Margin = 10 }; Button button = new Button { BackgroundColor = Color.FromArgb("#fff"), TextColor = Color.FromArgb("#01579B"), Text = "Save", Margin = 10 }; // определяем триггер данных DataTrigger dataTrigger = new DataTrigger(typeof(Button)) { // привязка триггера Binding = new Binding { Source = entry, Path = "Text.Length" }, Value = 0 }; // добавляем набор сеттеров dataTrigger.Setters.Add(new Setter { Property = Button.BackgroundColorProperty, Value = Colors.LightGray }); dataTrigger.Setters.Add(new Setter { Property = Button.TextColorProperty, Value = Colors.Gray }); dataTrigger.Setters.Add(new Setter { Property = Button.IsEnabledProperty, Value = false }); // добавляем триггер к кнопке button.Triggers.Add(dataTrigger); Content = new StackLayout { Padding = 10, Children = { entry, button } }; } } }
В качестве объекта отслеживания данных необязательно должен выступать элемент инстрфейса, это может быть произвольный объект. Например, пусть у нас будет следующий класс Person:
public class Person : INotifyPropertyChanged { string name = ""; public event PropertyChangedEventHandler PropertyChanged; public string Name { get => name; set { if (name != value) { name = value; OnPropertyChanged("Name"); } } } public void OnPropertyChanged(string prop = "") { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); } }
Класс Person реализует интерфейс INotifyPropertyChanged, поэтому может извещать систему обо всех изменениях в свойстве Name.
Создадим один объект этого класса и будем отслеживать его свойство Name:
<?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" xmlns:local ="clr-namespace:HelloApp" x:Class="HelloApp.MainPage"> <ContentPage.Resources> <local:Person x:Key="person" Name="Tom" /> </ContentPage.Resources> <StackLayout Padding="10"> <Entry Text="{Binding Source={x:StaticResource person}, Path=Name}" Margin="10" /> <Label Text="Привет" TextColor="#01579B" Margin="10"> <Label.Triggers> <DataTrigger TargetType="Label" Binding="{Binding Source={StaticResource person}, Path=Name}" Value="admin"> <Setter Property="Text" Value="Привет админ!"/> <Setter Property="TextColor" Value="Red"/> </DataTrigger> </Label.Triggers> </Label> </StackLayout> </ContentPage>
Здесь определен один ресурс - объект Person. Свойство Text элемента Entry привязано к свойству Name объекта Person. Но кроме того, триггер данных в элементе Label также привязан к свойству Name объекта Person. И если это свойство равно "admin", то выводит в Label красным цветом текст "Привет админ!"