Триггер данных срабатывает, когда привязанные к триггеру данные соответствуют определенному условию. В этом типе триггеров используется привязка.
Триггеры данных
Если триггер свойств отслеживает свойства элемента, к которому он применен, то триггер данных, благодаря привязке, может отслеживать внешний объект и срабатывать при выполнении определенных условий. Триггеры данных определяются с помощью объекта DataTrigger
. Рассмотрим следующий пример:
<Entry x:Name="entry" Placeholder="Этот триггер отключит кнопку, если длина текста будет равна нулю"/> <Button Text="Отправить"> <Button.Triggers> <DataTrigger TargetType="Button" Binding="{Binding x:DataType='Entry', Source={x:Reference entry}, Path=Text.Length}" Value="0"> <Setter Property="IsEnabled" Value="False"></Setter> </DataTrigger> </Button.Triggers> </Button> </VerticalStackLayout>
Здесь DataTrigger
применяется к кнопке Button
(это элемент, который меняет свой внешний вид) и отслеживает свойство Text.Length
у элемента Entry (это объект данных у которого отслеживается состояние)
Триггер можно прочитать так: если у элемента Entry
с именем entry
свойство Text.Length = 0
, то свойство IsEnabled
необходимо установить в значение false
. При запуске приложения кнопка будет активна, несмотря на то, что Entry
будет по умолчанию пустой:Если написать что-то в
Entry
и потом удалить — сработает триггер данных:
Отслеживание произвольного объекта
Благодаря механизму привязки, DataTrigger
может реагировать не только на изменение свойств каких-то визуальных элементов управления, но и на изменение свойств вообще любых объектов, к которым можно сделать привязку. Например, воспользуемся классом из части про интерфейс INotifyPropertyChanged
. Вот как он выглядел:
public class Project : INotifyPropertyChanged { string name = ""; bool isActive = false; double cost = 0; public string Name { get => name; set { if (name != value) { name = value; OnPropertyChanged(); } } } public bool IsActive { get => isActive; set { if (isActive != value) { isActive = value; OnPropertyChanged(); } } } public double Cost { get => cost; set { if (cost != value) { cost = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler? PropertyChanged; public void OnPropertyChanged([CallerMemberName] string prop = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop)); } }
Пусть наш триггер данных будет отключать кнопку, если свойство Name
у объекта Project
будет пустым. Перепишем наш пример следующим образом:
<?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="MauiApp17.MainPage" xmlns:local="clr-namespace:MauiApp17"> <ContentPage.Resources> <ResourceDictionary> <local:Project x:Key="project" IsActive="True" Name="Проект" Cost="0"/> </ResourceDictionary> </ContentPage.Resources> <ScrollView> <VerticalStackLayout Padding="30,0" Spacing="25"> <Entry Text="{Binding Source={StaticResource project}, Path=Name}"/> <Button Text="Отправить"> <Button.Triggers> <DataTrigger TargetType="Button" Binding="{Binding x:DataType='Project', Source={StaticResource project}, Path=Name.Length}" Value="0"> <Setter Property="IsEnabled" Value="False"></Setter> </DataTrigger> </Button.Triggers> </Button> </VerticalStackLayout> </ScrollView> </ContentPage>
Теперь текст элемента Entry
привязан к свойству нашего объекта типа Project
, а триггер — к длине текста свойства Name
. Можно запустить приложение и убедиться, что триггер срабатывает как только мы удаляем из Entry
текст и, следовательно, обнуляем длину текста у свойства объекта Project
.
Итого
Триггеры данных в .NET MAUI позволяют менять внешний вид элементов управления в зависимости от изменения свойств других объектов. Для настройки триггера используется привязка, что позволяет использовать для отслеживания объекты произвольных типов данных.