wpfxaml

How to change ItemControl item's foreground depending on condition


I have this class:

public class ShippingMethodMap
{
    public string ShippingMethod { get; set; }
    public int? MethodId { get; set; }
    public bool IsManaged { get; set; }
    public bool IsValid { get; set; }
}

Data is stored in ObservableCollection<ShippingMethodMap> ShippingMethodMapCollection, and displayed in XAML like

<ItemsControl ItemsSource="{Binding Path=ShippingMethodMapCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="1" BorderThickness="1" BorderBrush="LightGray">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="{Binding Path=ShippingMethod}">
                    </TextBlock>
                    <TextBox Grid.Column="1"
                             Text="{Binding Path=MethodId}"
                             IsEnabled="{Binding Path=IsManaged}">
                    </TextBox>
                </Grid>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Now - how can I set foreground color of TextBlock and TextBox (of distinct Item) to red, if ShippingMethodMap.IsValid = false?


Solution

  • You may add default TextBlock and TextBox Styles with a DataTrigger to the Border's Resources:

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="1" BorderThickness="1" BorderBrush="LightGray">
                <Border.Resources>
                    <Style x:Key="BaseStyle">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsValid}" Value="False">
                                <Setter Property="TextElement.Foreground" Value="Red"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                    <Style TargetType="TextBlock"
                           BasedOn="{StaticResource BaseStyle}"/>
                    <Style TargetType="TextBox"
                           BasedOn="{StaticResource BaseStyle}"/>
                </Border.Resources>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                               Text="{Binding Path=ShippingMethod}"/>
                    <TextBox Grid.Column="1"
                             Text="{Binding Path=MethodId}"
                             IsEnabled="{Binding Path=IsManaged}"/>
                </Grid>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>