Issue while mixing MultiBinding converter and Trigger in style

BlazingFrog picture BlazingFrog · May 5, 2011 · Viewed 13.2k times · Source

Setting the style in <UserControl.Resources> (assuming the converter returns the color Red)

<Style x:Key="FieldToValidate" TargetType="{x:Type TextBox}">
    <Setter Property="Background">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource VisualQueueOnErrorConverter}">
                <Binding RelativeSource="{RelativeSource self}" Path="Name" />
                <Binding RelativeSource="{RelativeSource AncestorType={x:Type DockPanel}}" Path="DataContext.ErrorFieldName" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" />
            </MultiBinding>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="Background" Value="Red">
            <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource self}}" />
            <Setter Property="Foreground" Value="White" />
        </Trigger>
    </Style.Triggers>
</Style>

and the control:

<TextBox  Name="FirstName" Text="{Binding FirstName}" Style="{StaticResource FieldToValidate}">  

The expected result is for the field FirstName to get the focus and the foreground color changed to white when the MultiBinding converter changes the background color to Red but, while the field's background changes to Red, it doesn't get the focus nor the new foreground color.

It almost seems like the XAML parser processes the Trigger before the property setter's MultiBinding converter.

Any and all suggestions welcome!

Answer

Thomas Levesque picture Thomas Levesque · May 5, 2011

I think the Red brush specified in the trigger and the Red brush returned by the converter are not considered equal (because they are different instances), so the trigger never executes. Anyway, it doesn't seem a very good idea to rely on the background color to trigger something...

You should change your converter so that it returns true when an error occurs, and use it as follows:

<Style x:Key="FieldToValidate" TargetType="{x:Type TextBox}">
    <Style.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource VisualQueueOnErrorConverter}">
                    <Binding RelativeSource="{RelativeSource self}" Path="Name" />
                    <Binding RelativeSource="{RelativeSource AncestorType={x:Type DockPanel}}" Path="DataContext.ErrorFieldName" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" />
                </MultiBinding>
            </DataTrigger.Binding>
            <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource self}}" />
            <Setter Property="Background" Value="Red" />
            <Setter Property="Foreground" Value="White" />
        </DataTrigger>
    </Style.Triggers>
</Style>

Also, in the name of your converter, you probably meant "visual cue", not "queue" ;)