4

I'm trying to create a single trigger will trigger on multiple possible options. I want to set the background to green when options are either "Reviewed" or "Completed". Then I want a second trigger to change the background to Yellow when "Pending" or "Yellow".

This answer pointed me towards it, but was incomplete and i couldn't make sense of it: https://stackoverflow.com/a/4660030/526704

Here's what I have now:

<Style x:Key="StatusCellTextBlock" TargetType="TextBlock">
    <Style.Triggers>
        <Trigger Property="Text" Value="Reviewed">
            <Setter Property="Background" Value="Green"/>
        </Trigger>
        <Trigger Property="Text" Value="Completed">
            <Setter Property="Background" Value="Green"/>
        </Trigger>
        <Trigger Property="Text" Value="Pending">
            <Setter Property="Background" Value="Yellow"/>
        </Trigger>
        <Trigger Property="Text" Value="Pending Review">
            <Setter Property="Background" Value="Yellow"/>
        </Trigger>
    </Style.Triggers>
</Style>

Here's the kind of thing i'm looking for: (some way to specify multiple values of the property that trigger the same setters. I have many more of these that I'd like to condense without repeating the same trigger many times)

<Style x:Key="StatusCellTextBlock" TargetType="TextBlock">
    <Style.Triggers>
        <Trigger Property="Text" Value="Reviewed" Value2="Completed">
            <Setter Property="Background" Value="Green"/>
        </Trigger>
        <Trigger Property="Text" Value="Pending" Value2="Pending Review">
            <Setter Property="Background" Value="Yellow"/>
        </Trigger>
    </Style.Triggers>
</Style>
Community
  • 1
  • 1
DLeh
  • 23,806
  • 16
  • 84
  • 128
  • 1
    [MultiTrigger](http://msdn.microsoft.com/en-us/library/system.windows.multitrigger.aspx) – Chris W. May 30 '14 at 20:55
  • 2
    @ChrisW. `MultiTrigger` requires all conditions to be met and not either (it's AND not OR) – dkozl May 30 '14 at 21:17
  • Does a converter makes it easier here? Take a look at 1. http://wpftutorial.net/ValueConverters.html and 2. http://stackoverflow.com/questions/378979/is-it-possible-to-use-a-converter-within-a-style – krishnaaditya May 30 '14 at 21:23
  • Like I said, @ChrisW, I tried to use a multitrigger given in the provided link but it wasn't a full answer. If you could provide a full answer that explains how I'd use this with an OR relationship that'd be great. – DLeh Jun 02 '14 at 12:38

2 Answers2

0

You can create your custom IValueConverter that would convert string into SolidColorBrush

public class TextToBackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        switch ((string)value)
        {
            case "Reviewed":
            case "Completed":
                return new SolidColorBrush(Colors.Green);
            case "Pending":
            case "Pending Review":
                return new SolidColorBrush(Colors.Yellow);
        }
        return DependencyProperty.UnsetValue;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

and then you don't even need Trigger. You can use Binding with Converter

<Style x:Key="StatusCellTextBlock" TargetType="TextBlock">
    <Setter 
        Property="Background" 
        Value="{Binding RelativeSource={RelativeSource Self}, Path=Text, Converter={StaticResource TextToBackgroundConverter}}"/>
</Style>

where TextToBackgroundConverter is defined somewhere in resources as

<Window.Resources>
    <local:TextToBackgroundConverter x:Key="TextToBackgroundConverter"/>
</Window.Resources>
dkozl
  • 32,814
  • 8
  • 87
  • 89
  • I dislike the converter answer because I have other setters that i'd like to have for this textblock, which mean's i'd have to create multiple converters. It also means I'm coding styles, where I would prefer to have them declared in XAML with all my other styles, and refer to static resources for the colors of the brushes, etc. I simplified my code a bit to make it standalone for SO. – DLeh Jun 02 '14 at 12:44
0

I devised a solution. I'm now using a converter to determine whether or not the value is given among the provided parameters. I send the options "Reviewed,Completed" as a parameter to the converter, which returns true if the text from the TextBlock is found anywhere in the parameter.

XAML:

    <Style TargetType="TextBlock" x:Key="StatusStyle">
        <Style.Triggers>
            <DataTrigger Value="True" Binding="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource OrConverter}, ConverterParameter=Reviewed;Completed}">
                <Setter Property="Foreground" Value="Green" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

Converter:

[ValueConversion(typeof(string), typeof(bool))]
public class MultiValueOrConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((string)parameter).Split(';').Contains((string)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}
DLeh
  • 23,806
  • 16
  • 84
  • 128