views:

2708

answers:

2

The following DataTemplate.DataTrigger makes the age display red if it is equal to 30.

How do I make the age display red if it is greater than 30?

<DataTemplate DataType="{x:Type local:Customer}">
    <Grid x:Name="MainGrid" Style="{StaticResource customerGridMainStyle}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="150"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Column="0" Grid.Row="0" Text="First Name" Margin="5"/>
        <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding FirstName}" Margin="5"/>
        <TextBlock Grid.Column="0" Grid.Row="1" Text="Last Name" Margin="5"/>
        <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding LastName}" Margin="5"/>
        <TextBlock Grid.Column="0" Grid.Row="2" Text="Age" Margin="5"/>
        <TextBlock x:Name="Age" Grid.Column="1" Grid.Row="2" Text="{Binding Age}" Margin="5"/>
    </Grid>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Age}">
            <DataTrigger.Value>30</DataTrigger.Value>
            <Setter TargetName="Age" Property="Foreground" Value="Red"/> 
        </DataTrigger>
    </DataTemplate.Triggers>

</DataTemplate>
+14  A: 

You could create a IValueConverter which converts an integer to a boolean based on the cutoff. Then use DataTrigger.Value of true (or false, depending on what you are returning).

WPF DataTriggers are strictly equality comparers if I remember correctly.

So something similar to:

public class CutoffConverter : IValueConverter {
    public object ConvertTo(object obj, Type type) {
        return ((int)obj) > Cutoff;
    }

    public object ConvertFrom(object obj, Type type) {
        throw new NotImplementedException();
    }

    public int Cutoff { get; set; }
}

Then use the following XAML.

<Window.Resources>
    <myNamespace:CutoffConverter x:Key="AgeConverter" Cutoff="30" />
</Window.Resources>

<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Path=Age,
                                   Converter={StaticResource AgeConverter}}">
        <DataTrigger.Value>true</DataTrigger.Value>
        <Setter TargetName="Age" Property="Foreground" Value="Red"/> 
    </DataTrigger>
</DataTemplate.Triggers>

The code above isn't unfortunately tested (And I can't remember the real IValueConverter interface). But it should point to the right direction at least.

Mikko Rantanen
alternatively you can use ConverterParameter to pass in the cutoff value if you need different values for different triggers:Binding="{Binding Path=Age, Converter={StaticResource AgeConverter}, ConverterParameter=30}"
Denis Troller
works as is, very helpful, thanks!
Edward Tanguay
@Denis, Didn't know of that! Thanks for the headsup!
Mikko Rantanen
A: 

I'd recommend is using a IValueConverter to bind to the Foreground element of the Age TextBlock and isolating the coloring logic there.

<TextBlock x:Name="Age" Grid.Column="1" Grid.Row="2" Text="{Binding Age}" Foreground="{Binding Path=Age, Converter={StaticResource AgeToColorConverter}}" Margin="5"/>

Then in the Code:

[ValueConversion(typeof(int), typeof(Brush))]
public class AgeToColorConverter : IValueConverer
{
   public object Convert(object value, Type target)
   {
      int age;
      int.Parse(value.ToString(), age);
      return (age >= 30 ? Brushes.Red : Brushes.Black);
   }
}
Drew McGhie