четверг, 30 июня 2011 г.

Создание простого триггера в WPF


В этой статье речь пойдёт о триггерах в WPF. С помощью триггеров можно менять поведение или внешний вид элементов управления на странице в зависимости от каких-либо событий иои значения какого-либо свойства.
Триггеры бывают трёх ипов. Давайте рассмотрим все по порядку.

Property Trigger

Первй из них это Property Trigger. Триггеры свойств активизируются, когда изменяется значение свойства.
WPF определяет свойства, которые соответствуют действиям пользователя, например, свойство IsMouseOver, которое получает значение true, когда пользователь наводит курсор на UIElement, или соответствующее свойство IsMouseOver объекта ContentElement. Представление действий пользователя в значениях свойств, а также использование элемента Trigger позволяет стилям WPF изменять значения свойств, основанные на действиях пользователя (все из кода).
Свойства, измененные триггерами, автоматически сбрасываются до предыдущего значения, когда условие триггера больше не удовлетворяется. Триггеры оптимизированы для промежуточных состояний, которые должны изменяться и возвращаться к исходному состоянию, например, состояние IsPressed для кнопки Button и состояние IsSelected для элемента ListBoxItem. Данное свойство Property является свойством зависимостей.

Обратите внимание, что необходимо указать свойства Property и Value для объекта Trigger, чтобы триггер работал правильно. Если одно из свойств или оба свойства не заданы, генерируется исключение.

Свойство Setters объекта Trigger может состоять только из объектов Setter. При добавлении дочернего объекта Setter в объект Trigger он неявно добавляется в коллекцию SetterBaseCollection объекта Trigger. Объекты EventSetter не поддерживаются; только Style.Setters поддерживает объекты EventSetter.

В следующем примере демонстрируется именованный стиль Style, доступный для элементов управления Button. Стиль Style определяет два элемента Trigger, первый из которых изменяет свойство Foreground и FontSize кнопки, когда свойство IsMouseOver равно true., а второй делает то е самое только по событию IsPressed равно true.

<Window x:Class="TriggerDemo.PropertyTriggerWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="PropertyTriggerWindow" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="LightBlue" />
            <Setter Property="FontSize" Value="17" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Red" />
                    <Setter Property="FontSize" Value="22" />
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Foreground" Value="Yellow" />
                    <Setter Property="FontSize" Value="22" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Button Width="200" Height="30" Content="Click me!" />
    </Grid>
</Window>



Multi Trigger

Если необходимо установить триггер, когда одно или более свойств имеют определённое значене, можно воспользоваться классом MultiTrigger.

MultiTrigger позволяет задать значения свойств или запускать действия на основе коллекции условий Condition. Условие выполняется, если значение свойства (указанное свойством Property класса Condition) элемента соответствует указанному Value. Данное сравнение является проверкой равенства ссылок. Можно использовать переключатели или свойства EnterActions и ExitActions, чтобы применить изменения или запустить действия, когда соблюдаются все условия.

Свойство Setters объекта MultiTrigger может состоять только из объектов Setter. Добавление дочернего Setter к объекту MultiTrigger неявно добавляет его к SetterBaseCollection для объекта MultiTrigger. Объекты EventSetter не поддерживаются; только свойство Style.Setters поддерживает объекты EventSetter.

В следующем примере определяется стиль для элементов TextBox. Триггер смотрит,  если  "IsEnabled"="True и "Text ="Test, то то свойство Foreground устанавливается в Red.

<Window x:Class="TriggerDemo.MultiTriggerWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MultiTriggerWindow" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsEnabled" Value="True" />
                        <Condition Property="Text" Value="Test" />
                    </MultiTrigger.Conditions>
                    <MultiTrigger.Setters>
                        <Setter Property="Foreground" Value="Red" />
                    </MultiTrigger.Setters>
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <TextBox />
    </Grid>
</Window>



Data Trigger

Представляет триггер, применяющий значения свойства или выполняющий действия при соответствии связанных данных указанному условию. DataTrigger позволяет устанавливать значения свойств, если значение свойства объекта данных соответствует заданному Value. Например, при отображении перечня объектов Employee может потребоваться изменить основной цвет в соответствии с текущим присутствием каждого Employee's. Например, Employees, находящиеся в данный момент в отпуске, отображаются фиолетовым цветом. В некоторых сценариях более предпочтительным может быть создание преобразователя или использование DataTemplateSelector. Дополнительные сведения см. в разделе Общие сведения о шаблонах данных.

Обратите внимание на необходимость указания свойств Binding и Value на DataTrigger для обеспечения возможности использования триггера данных. Если одно из свойств или оба свойства не указаны, генерируется исключение.
Свойство Setters объекта DataTrigger может состоять только из объектов Setter. Добавление дочернего Setter к объекту DataTrigger явно добавляет его к SetterBaseCollection для объекта DataTrigger. Объекты EventSetter не поддерживаются; только Style.Setters поддерживает объекты EventSetter.

В следующем примере ItemsSource, принадлежащий ListBox привязан к коллекции объектов класса Book. Объекты Book имеют свойства Title и Publisher.
Каждый элемент ListBoxItem списка ListBox отображает объект Book. Style в данном примере применяется к каждому элементу ListBoxItem.

DataTrigger указан таким образом, что если в качестве Publisher значение " Wrox Press ", то основным цветом соответствующего ListBoxItem является красный, а если Publisher="Dummies" или “Sybex”, то бэкграунд устанавливается в жёлтый и голубой соответственно.

<Window x:Class="TriggerDemo.DataTriggerWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Data Trigger Window" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="ListBoxItem">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Publisher}" Value="Wrox Press">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Publisher}" Value="Dummies">
                    <Setter Property="Background" Value="Yellow" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Publisher}" Value="Sybex">
                    <Setter Property="Background" Value="LightBlue" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <ListBox x:Name="list1" />
    </Grid>
</Window>



Вот класс Book, объекты которого мы и отображаем в ListBox.

    public class Book
    {
        public string Title { get; set; }
        public string Publisher { get; set; }

        public override string ToString()
        {
            return Title;
        }
    }

И напоследок опишу код главного окна который запускает все эти демонстрационные приложения.

<Window x:Class="TriggerDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="240" Width="500">
    <StackPanel>
        <Button Content="Property Trigger" Click="OnPropertyTrigger" Margin="5" />
        <Button Content="Multi Trigger" Click="OnMultiTrigger" Margin="5" />
        <Button Content="Data Trigger" Click="OnDataTrigger" Margin="5" />
    </StackPanel>

</Window>



И приведу cs код, в котором описаны обработчики кнопок главного окна.

   public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OnPropertyTrigger(object sender, RoutedEventArgs e)
        {
            new PropertyTriggerWindow().Show();
        }

        private void OnMultiTrigger(object sender, RoutedEventArgs e)
        {
            new MultiTriggerWindow().Show();
        }

        private void OnDataTrigger(object sender, RoutedEventArgs e)
        {
            new DataTriggerWindow().Show();
        }
    }

 Вот что должно было примерно получится. Надеюсь статья была интересна для вас.

1 комментарий: