2

I have DependencyProperty State of Flags enum type. I want to change some element border color due to changing of the State property. For some reasons I can not operate with the element directly but only by setting its Style.

How can I change following code to make it possible not to check exact value of State but check whether it contains desired flag?

<Style.Triggers>
            <Trigger Property="State" Value="None">
                <Setter Property="StateBorderBrush" Value="Transparent"/>
            </Trigger>
            <Trigger Property="State" Value="Covered">
                <Setter Property="StateBorderBrush" Value="Blue"/>
            </Trigger>
            <Trigger Property="State" Value="Selected">
                <Setter Property="StateBorderBrush" Value="Red"/>
            </Trigger>
            <Trigger Property="State" Value="contains flag 'Controlled'">
                <Setter Property="StateBorderBrush" Value="Orange"/>
            </Trigger>
        </Style.Triggers>
Serge P.
  • 327
  • 1
  • 3
  • 16
  • You could use a converter to check the value, otherwise `xaml` offers limited functionality when using comparison i.e. it can only check for equality and equality only, hence `Converter` would be the easiest option. Here is a [link](http://wpftutorial.net/ValueConverters.html) HTH – XAMlMAX Jan 14 '15 at 16:04
  • Where should I put converter? Neither Property nor Value of Trigger can accept binding as a value. – Serge P. Jan 15 '15 at 06:22

4 Answers4

2

As far as I'm concerned, the only solution is converter:

 public class EnumFlagConverter : ValueConverter
{
    public string FlagValue { get; set; }
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Enum en = value as Enum;
        var enumFlag = Enum.Parse((Type)parameter, FlagValue);
        return en.HasFlag((Enum)enumFlag);
    }
}

And the xaml binding:

 <DataTrigger Binding="{Binding State,Converter={cnv:EnumFlagConverter FlagValue='Locked'}, ConverterParameter={x:Type viewModels:SourceControlState}}"
                         Value="True">
                <Setter Property="Source"
                        TargetName="srcCtrlStatusIndicator"
                        Value="{StaticResource ImageSourceCheckedOutBySomeoneElse9x9}" />                  

            </DataTrigger>
Mr.B
  • 3,484
  • 2
  • 26
  • 40
1

Check out Lars's generic answer to a similar question here: Using a generic converter

His solution works with enum flags that are not mutually exclusive. That allowed me to use this XAML.

<DataTrigger Binding="{Binding Path=State, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static enums:MyStatesEnum.MyEnumFlagValue}}" Value="True">
                <Setter Property="BorderBrush" Value="Red"/>
            </DataTrigger>
Community
  • 1
  • 1
0

Finally I achieved it by using DataTrigger with relative binding to Self:

<DataTrigger Binding="{Binding Path=State, RelativeSource={RelativeSource Self}}" Value="None">
      <Setter Property="StateBorderBrush" Value="Transparent"/>
</DataTrigger>

Then it is possible to expand Binding element and apply appropriate converter

Serge P.
  • 327
  • 1
  • 3
  • 16
0

This is how you test for an enum in a trigger:

    <ControlTemplate.Triggers>
        <Trigger Property="ViewState"
                 Value="{x:Static constants:LicenseViewState.License}">
            <Setter Property="Visibility"
                    Value="Collapsed"
                    TargetName="ProductComboBoxField">
            </Setter>
        </Trigger>
    </ControlTemplate.Triggers>
Quark Soup
  • 4,272
  • 3
  • 42
  • 74