0

Here is the psuedo code for what I want to do

IF NOT ISDIRTY
    THEN VISIBILITY EQ VISIBILITY.COLLAPSED

IF ISDIRTY AND ISVALID        
    THEN VISIBILITY EQ VISIBILITY.VISIBLE AND COLOR = GREEN

IF ISDIRTY AND NOT ISVALID        
    THEN VISIBILITY EQ VISIBILITY.VISIBLE AND COLOR = RED

The Style for a ToggleButton below gets the conditions right on the first update but doesn't change thereafter.

For example, if I make a change that doesn't make the vm invalid, the color is correctly Green. But if I then make a change to make the vm invalid, it stays green, when it should be Red. Conversely, if the first update makes the vm invalid, the color is correctly set to Red, but a second update that corrects the invalid error but leaves the vm dirty does not change the color to Green.

What am I doing wrong?

I haven't tried the Visual State Manager yet, but would that be a preferred way to go? How might that look?

Usage

        <Ellipse Style="{StaticResource EditedStateIndicatorStyle}"/>

the Style

<Style x:Key="EditedStateIndicatorStyle" TargetType="{x:Type Ellipse}">
    <Setter Property="Width" Value="8" />
    <Setter Property="Height" Value="8" />
    <Setter Property="Margin" Value="8,0"/>
    <Setter Property="SnapsToDevicePixels" Value="false" />
    <Setter Property="Focusable" Value="False" />

    <Style.Triggers>

        <!-- Dirty, && NOT Valid -->
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsDirty}" Value="true"/>
                <Condition Binding="{Binding IsValid}" Value="false"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="Fill" Value="Red"/>
            <Setter Property="ToolTip" Value="You got errors, fool!"/>
        </MultiDataTrigger>

        <!-- Dirty, but Valid -->
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsDirty}" Value="true"/>
                <Condition Binding="{Binding IsValid}" Value="true"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="Fill" Value="Green"/>
            <Setter Property="ToolTip" Value="You made changes!"/>
        </MultiDataTrigger>

        <!-- Not Dirty, don't show anything -->
        <DataTrigger Binding="{Binding IsDirty}" Value="false">
            <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </Style.Triggers>

</Style>
Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
Berryl
  • 12,471
  • 22
  • 98
  • 182
  • 1
    And your VM is implementing INPC? – LPL Jun 29 '12 at 14:27
  • @LPL. Yes, of course BUT I had introduced a bug that was preventing notification on IsValid from firing!! Would you have laid the triggers out the same? Have you got any insights into VSM usage? Please make an answer so the next fool might go back and check the obvious first. – Berryl Jun 29 '12 at 14:50

2 Answers2

2

If your ViewModel is implementing INotifyPropertyChanged first ensure that it is properly raising the event. Said that I recommend a simplification:

<Style TargetType="{x:Type Ellipse}">
    ...
    <Setter Property="Fill" Value="Green" />
    <Setter Property="ToolTip" Value="You made changes!" />

    <Style.Triggers>
        <!-- Dirty, but NOT Valid -->
        <DataTrigger Binding="{Binding IsValid}" Value="false">
            <Setter Property="Fill" Value="Red" />
            <Setter Property="ToolTip" Value="You got errors, fool!" />
        </DataTrigger>

        <!-- Not Dirty, don't show anything -->
        <DataTrigger Binding="{Binding IsDirty}" Value="false">
            <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
LPL
  • 16,827
  • 6
  • 51
  • 95
1

Trying setting the fill to a default color (Green) as a setter outside the trigger (i.e. in the style)

Adam Mills
  • 7,719
  • 3
  • 31
  • 47