'How to change WPF Rectangle Style Programatically

[EDIT] *I had forgotten to include the Exception returned

'System.Windows.Style' is not a valid value for property 'Fill'*

This is my first post, I've already done lots of searching for questions where this might have already been answered to no success. I'm a complete noob when it comes to MVVM, Prism, and WPF and I have been thrown in the deep end on this one.

I wish to change the contents of 2 rectangles depending on a boolean in the Model (Binding Passed).

if a test returns Pass (bool True) then we display colour Green for first rectangle, and the second rectangle will display the UserControl.Resource Style x:Key="RectanglePass". If test fails, then first rectangle is red, and second displays UserControl.Resource Style x:Key="RectangleFail"

I have the following xaml code:

<UserControl x:Class="Integration.Memjet.Aoqc.Views.ProcessResultView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

 <UserControl.Resources>
    <Style x:Key="RectangleFail" TargetType="Rectangle">
        <Setter Property="Fill">
            <Setter.Value>
                <VisualBrush>
                    ....
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="RectanglePass" TargetType="Rectangle">
        <Setter Property="Fill">
            <Setter.Value>
                <VisualBrush>
                    ....
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="60"></RowDefinition>
        <RowDefinition Height="60"></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20">PASS</Label>
    <Rectangle Name="rectStatus" Grid.Row="1">
        <Rectangle.Style>
            <Style TargetType="{x:Type Rectangle}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Passed}" Value="True">
                        <Setter Property="Fill" Value="Green" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Passed}" Value="False">
                        <Setter Property="Fill" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Rectangle.Style>
    </Rectangle>

    <Rectangle Name="rectStatusImg" Width="120" Height="120" Grid.Row="2" >
        <Rectangle.Style>
            <Style TargetType="{x:Type Rectangle}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Passed}" Value="True">
                        <Setter Property="Fill" Value="{StaticResource RectanglePass}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Passed}" Value="False">
                        <Setter Property="Fill" Value="{StaticResource RectangleFail}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Rectangle.Style>
    </Rectangle>
</Grid>
</UserControl>

The above doesn't work and returns an exception. If I was to replace the second Rectangle tag (rectStatusImg) with this line;

<Rectangle Name="rectStatusImg" Style="{StaticResource RectanglePass}" Width="120" Height="120" Grid.Row="2" ></Rectangle>

the xaml works and produces the expected result! But I wish to bind it to the Boolean Passed so I can change it programmatically.

I really hope I was able to explain my problem here.

Thank you for your help in advance, this site has always been a treasure and a great help.

Cheers, Simon



Solution 1:[1]

define two visual brushes in your resource and create a style of rectangle with data trigger like

  <VisualBrush x:Key="FailBrush">Black</VisualBrush>
    <VisualBrush x:Key="PassBrush">Red</VisualBrush>

    <Style x:Key="ColorRectangleStyle" TargetType="Rectangle">
        <Setter Property="Fill" Value="{StaticResource FailBrush}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Passed}" Value="False">
                <Setter Property="Fill" Value="{StaticResource PassBrush}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

and use it in rectangle like

<Rectangle Name="rectStatusImg" Width="120" Height="120" Grid.Row="2" Style="{StaticResource ColorRectangleStyle}" />

Hope it helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 D J