How to Use DataTrigger to set a property defined in the ViewModel in WPF

Kevin picture Kevin · Jan 26, 2011 · Viewed 8.5k times · Source

I am writing a XAML file which use DataTrigger to set a property in the ViewModel. The ViewModel class defined as:

public class ShellModel : INotifyPropertyChanged
{    
    public Brush ForegroundBrush
    {
        get; set;
    }

    ....................
}

I want to use DataTrigger in the View.xaml to set the property ForegroundBrush. The XAML I wrote is:

<StatusBar Name="statusBar" Grid.Row="3">
    <StatusBarItem>
        <StatusBarItem.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding HasError}" Value="True">
                        <Setter Property="ForegroundBrush" Value="Red" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding HasError}" Value="False">
                        <Setter Property="ForegroundBrush" Value="Black" />
                    </DataTrigger>
                        </Style.Triggers>
            </Style>
        </StatusBarItem.Style>
        <TextBlock Name="statusBarMessage" Foreground="{Binding ForegroundBrush}" Text="{Binding StatusMessage}"></TextBlock>
     </StatusBarItem>
     ........................

This does not compile. When I changed the

     <Setter Property="ForegroundBrush" Value="Black" />     

to

     <Setter Property="ShellModel.ForegroundBrush" Value="Black" />

it gives me error:

Dependency property field missing ....

How shall I write this so that the DataTrigger can set the property ForegroundBrush in the ViewModel?

Answer

Botz3000 picture Botz3000 · Jan 26, 2011

Setters in your DataTriggers should change properties of your UI elements only (and also they only work with DependencyProperties).
Set the Foregound Property of your StatusBarItem directly and set the TargetType of the Style. That should help.

   <Style TargetType="{x:Type StatusBarItem}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding HasError}" Value="True">
                <Setter Property="Foreground" Value="Red" />
            </DataTrigger>
            <DataTrigger Binding="{Binding HasError}" Value="False">
                <Setter Property="Foreground" Value="Black" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

Having information about the visual representation in your ViewModel is usually not a good idea anyway.