mvvmsilverlight

Dynamic setting of Style property based on model value


Class Question represents a question and it's answer. My application renders an ObservableCollection of Question objects. Each Question is rendered as a StackPanel that contains a TextBlock and a TextBox. The questions are rendered using an ItemsControl and I set the Style of the Questions's StackPanel using a StaticResource key IncorrectQuestion (defined in UserControl.Resources).

In UserControl.Resources section I defined a key CorrectQuestion which I need to apply to the Question's StackPanel when the user correctly answers. How to dynamically change the Style of the StackPanel within the constraints of a ViewModel class (I don't want to put style selection code in the View)? Question class has an IsCorrect property which is set when the correction is answered. I'd like to reflect the IsCorrect value as a Style selection.


Solution

  • Using a value converter is a solution.

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.Resources>
            <local:BoolToStyleConverter x:Key="Correctness">
                <local:BoolToStyleConverter.FalseValue>
                    <Style TargetType="TextBox">
                        <Setter Property="Background" Value="Salmon" />
                    </Style>
                </local:BoolToStyleConverter.FalseValue>
                <local:BoolToStyleConverter.TrueValue>
                    <Style TargetType="TextBox">
                        <Setter Property="Background" Value="AliceBlue" />
                    </Style>
                </local:BoolToStyleConverter.TrueValue>
            </local:BoolToStyleConverter>
        </Grid.Resources>
        <ItemsControl ItemsSource="{Binding}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Question}" />
                        <TextBox x:Name="Answer" Text="{Binding Answer, Mode=TwoWay}"
                           Style="{Binding IsCorrect, Converter={StaticResource Correctness}}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>        
    </Grid>
    

    You can find the basis for the BoolToStyleConverter is based on this blog post. Created as:-

    public class BoolToStyleConverter : BoolToValueConverter<Style> { }