Триггеры данных

Последнее обновление: 19.12.2022

Триггеры данных (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" />
Триггер данных DataTrigger в .NET MAUI и C#

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

<?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, то делаем кнопку недоступной и устанавливаем для нее соответствующие цвета для текста и фона.

Триггер данных в приложении на .NET MAUI и C#

Триггеры данных в коде

Аналогичный триггер данных в коде 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 красным цветом текст "Привет админ!"

Триггер данных и отслеживание произвольных объектов в приложении на .NET MAUI и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850