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

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

Триггеры данных (data triggers) позволяют отслеживать изменение свойств объектов. В Xamarin Forms триггеры данных представлены классом DataTrigger. Рассмотрим, как его использовать.

В качестве объекта, за свойствами которого будет следить триггер данных, возьмем следующий класс Phone:

using System.ComponentModel;

public class Phone : INotifyPropertyChanged
{
    private string title;
    private string company;
    private int price;

    public string Title
    {
        get { return title; }
        set
        {
            title = value;
            OnPropertyChanged("Title");
        }
    }
    public string Company
    {
        get { return company; }
        set
        {
            company = value;
            OnPropertyChanged("Company");
        }
    }
    public int Price
    {
        get { return price; }
        set
        {
            price = value;
            OnPropertyChanged("Price");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

Важно отметить, что если мы хотим динамически отслеживать изменение свойств объекта, то класс, представляющий этот объект, должен реализовать интерфейс INotifyPropertyChanged.

В коде xaml у главной страницы определим пользовательский интерфейс с привязкой к объекту Phone:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HelloApp;assembly=HelloApp"
             x:Class="HelloApp.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:Phone x:Key="phone" Title="iPhone 7" Company ="Apple" Price="56000" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid BindingContext="{StaticResource phone}">
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="60" />
            <RowDefinition Height="30" />
            <RowDefinition Height="60" />
            <RowDefinition Height="30" />
            <RowDefinition Height="60" />
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Text="Модель" />
        <Label Grid.Row="2" Text="Компания"  />
        <Label Grid.Row="4" Text="Цена"   />

        <Entry Grid.Row="1" Text="{Binding Path=Title}" />
        <Entry Grid.Row="3" Text="{Binding Path=Company}">
            <Entry.Triggers>
                <DataTrigger Binding="{Binding Company}" TargetType="Entry" Value="Microsoft">

                    <Setter Property="TextColor" Value="#004D40"  />
                    <Setter Property="BackgroundColor" Value="#80CBC4"  />

                </DataTrigger>
            </Entry.Triggers>
        </Entry>
        <Entry Grid.Row="5" Text="{Binding Path=Price}"   />

    </Grid>
</ContentPage>

Здесь установлена привязка трех элементов Entry к разным свойствам объекта Phone, который определен в ресурсах. Причем для второго элемента Entry добавлен триггер данных:

<Entry Grid.Row="3" Text="{Binding Path=Company}">
  <Entry.Triggers>
    <DataTrigger Binding="{Binding Company}" TargetType="Entry" Value="Microsoft">
          
       <Setter Property="TextColor" Value="#004D40"  />
       <Setter Property="BackgroundColor" Value="#80CBC4"  />
          
    </DataTrigger>
  </Entry.Triggers>
</Entry>

У триггера данных в обязательном порядке должно быть установлено свойство TargetType, которое указывает на тип элемента, к которому применяется триггер.

Также у триггера через свойство Binding задается привязка к определенному свойству объекта Phone (в данном случае свойство Company). А через свойство Value определяется значение, при котором будет срабатывать триггер. То есть в данном случае триггер будет срабатывать, когда свойство Company объекта Phone получит значение "Microsoft".

Вся работа триггера заключается в установке свойств объекта Entry. Для этого у триггера в коллекцию Setters добавляются объекты Setter, которые указывают, какое свойство будет изменяться и какое значение оно получит. То есть в данном случае, когда свойство Company объекта Phone получит значение "Microsoft", свойство BackgroundColor у Entry получит значение "#80CBC4", свойство TextColor - значение "#004D40".

В данном случае триггер привязан к тому же свойству, к которому привязан и объект Entry. Однако это необязательно, они могут быть привязан к разным свойствам. И теперь, если мы запустим приложения и введем в поле, которое представляет компанию, строку "Microsoft", то сработает наш триггер данных:

DataTrigger in Xamarin Forms

Создание аналогичного триггера данных в коде c#:

Entry companyValueEntry = new Entry();
Binding companyBinding = new Binding { Source = phone, Path = "Company" };
companyValueEntry.SetBinding(Entry.TextProperty, companyBinding);

DataTrigger dataTrigger = new DataTrigger(typeof(Entry))
{
    Binding = new Binding { Source = phone, Path = "Company" },
    Value = "Microsoft"
};
dataTrigger.Setters.Add(new Setter { Property = Entry.BackgroundColorProperty, Value = Color.FromHex("#80CBC4") });
dataTrigger.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Color.FromHex("#004D40") });

companyValueEntry.Triggers.Add(dataTrigger);

Полный пример:

using Xamarin.Forms;

namespace HelloApp
{
    public partial class MainPage : ContentPage
    {
        Phone phone;
        public MainPage()
        {
            phone = new Phone { Title = "iPhone 7", Company = "Apple", Price = 56000 };

            Grid grid = new Grid
            {
                RowDefinitions =
                {
                    new RowDefinition { Height = 50 },
                    new RowDefinition { Height = 60 },
                    new RowDefinition { Height = 50 },
                    new RowDefinition { Height = 60 },
                    new RowDefinition { Height = 50 },
                    new RowDefinition { Height = 60 }
                }
            };

            Label titleHeaderLabel = new Label { Text = "Модель" };
            Label companyHeaderLabel = new Label { Text = "Компания" };
            Label priceHeaderLabel = new Label { Text = "Цена" };

            Entry titleValueEntry = new Entry();
            Binding titleBinding = new Binding { Source = phone, Path = "Title" };
            titleValueEntry.SetBinding(Entry.TextProperty, titleBinding);

            Entry companyValueEntry = new Entry();
            Binding companyBinding = new Binding { Source = phone, Path = "Company" };
            companyValueEntry.SetBinding(Entry.TextProperty, companyBinding);

            DataTrigger dataTrigger = new DataTrigger(typeof(Entry))
            {
                Binding = new Binding { Source = phone, Path = "Company" },
                Value = "Microsoft"
            };
            dataTrigger.Setters.Add(new Setter { Property = Entry.BackgroundColorProperty, Value = Color.FromHex("#80CBC4") });
            dataTrigger.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Color.FromHex("#004D40") });

            companyValueEntry.Triggers.Add(dataTrigger);

            Entry priceValueEntry = new Entry();
            Binding priceBinding = new Binding { Source = phone, Path = "Price" };
            priceValueEntry.SetBinding(Entry.TextProperty, priceBinding);
            

            grid.Children.Add(titleHeaderLabel, 0,0);
            grid.Children.Add(companyHeaderLabel, 0, 2);
            grid.Children.Add(priceHeaderLabel, 0, 4);

            grid.Children.Add(titleValueEntry, 0, 1);
            grid.Children.Add(companyValueEntry, 0, 3);
            grid.Children.Add(priceValueEntry, 0, 5);
            

            Content = grid;
        }
    }
}

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

Допустим, в коде страницы определено свойство Phones, которое содержит некоторый набор объектов:

using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace HelloApp
{
    public partial class MainPage : ContentPage
    {
        public ObservableCollection<Phone> Phones { get; set; }
        public MainPage()
        {
            InitializeComponent();

            Phones = new ObservableCollection<Phone>
            {
                new Phone { Title = "HTC U Ultra", Company = "HTC", Price = 36000 },
                new Phone {Title="Huawei P10", Company="Huawei", Price=35000 },
                new Phone {Title="iPhone 6S", Company="Apple", Price=42000 },
                new Phone {Title="LG G 6", Company="LG", Price=42000 },
                new Phone {Title="iPhone 7", Company="Apple", Price=52000 }
            };
            this.BindingContext = this;
        }
    }
}

В коде XAML у страницы применим триггер данных, чтобы выделить цветом те объекты, которые принадлежат определенной компании:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HelloApp;assembly=HelloApp"
             x:Class="HelloApp.MainPage">
    <StackLayout>
        <ListView HasUnevenRows="True" ItemsSource="{Binding Phones}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label Text="{Binding Title}" FontSize="Medium">
                                <Label.Triggers>
                                    <DataTrigger TargetType="Label" 
            Binding="{Binding Company}" Value="Apple">
   <Setter Property="TextColor" Value="Red" />
                                    </DataTrigger>
                                </Label.Triggers>
                            </Label>
                            <Label Text="{Binding Price}">
                                <Label.Triggers>
                                    <DataTrigger TargetType="Label" 
            Binding="{Binding Company}" Value="Apple">
   <Setter Property="TextColor" Value="Red" />
                                    </DataTrigger>
                                </Label.Triggers>
                            </Label>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>
Триггер данных в Xamarin Forms
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850