views:

80

answers:

1

I have an Adorner in XAML that I'm using for ErrorValidation. Basically I have a grid that I want to display on two conditions (if the "AdornedElement" IsFocused or IsMouseOver).

Below is a code snippet where I'm binding - successfully - to the IsFocused of the AdornedElement, but as you can tell that only solves 1/2 the conditions. Now I can't pass another binding into the converter, nor can I create a property that handles both (needs to be XAML only solution).

 <AdornedElementPlaceholder
                            x:Name="errorAdorner" />
                    ...

  <Grid
     x:Name="ErrorDetails"
     Visibility="{Binding ElementName=errorAdorner, Path=AdornedElement.IsFocused, Converter={StaticResource BooleanToVisibilityConverter}}" />

                   ...

What I want to do is use triggers to handle this, the only problem is I can't access the AdornedElement's properties on a trigger.

Something like this ...

        <Trigger
            SourceName="errorAdorner"
            Property="AdornedElement.IsFocused"
            Value="True">
            <Setter
                TargetName="ErrorDetails"
                Property="Visibility"
                Value="Visible" />
        </Trigger>

This would also help as part of what I want to do is trigger animations, rather than just setting the visibility.

Any help would be great.

+2  A: 

What you're looking for is called a MultiBinding and is built into WPF (though not in Silverlight.)

<Grid>
    <Grid.Resources>
        <c:BooleanPairToVisibilityConverter x:Key="booleanPairToVisibility" />
    </Grid.Resources>
    <Grid.Visibility>
        <MultiBinding Converter="{StaticResource booleanPairToVisibility}">
            <Binding ElementName="errorAdorner" Path="AdornedElement.IsFocused" />
            <Binding ElementName="errorAdorner" Path="AdornedElement.IsMouseOver" />
        </MultiBinding>
    </Grid.Visibility>
</Grid>

Then you need a simple IMultiValueConverter to translate those values into a Visibility:

public class BooleanPairToVisibilityConverter : IMultiValueConverter {
    public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture )
    {
        if ( 2 != values.Length ) throw new ArgumentException( "values" );
        return ( (bool)values[0] || (bool)values[1] ) ? Visibility.Visible : Visibility.Collapsed;
    }

    public object[] ConvertBack( object value, Type[] targetTypes, object parameter, CultureInfo culture )
    { throw new NotSupportedException(); }
}

Admittedly, this doesn't solve the second question about how to do this with Triggers. I wouldn't...

If you want an animation around a change in the ErrorDetails element's visibility, set the trigger on the visibility property directly - it should get invoked when the MultiBinding causes the DependencyProperty's value to change. Also, it might be worth considering Behaviors to accomplish that instead as they're a little more straightforward for attaching simple animations.

hemp