Search code examples
wpfxamlstyles

Binding ConverterParameter


Is there a way I could do this in a Style:

<Style TargetType="FrameworkElement">
    <Setter Property="Visibility">
        <Setter.Value>
            <Binding Path="Tag"
                RelativeSource="{RelativeSource AncestorType=UserControl}"
                Converter="{StaticResource AccessLevelToVisibilityConverter}"
                ConverterParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag}" />                        
        </Setter.Value>
    </Setter>
</Style>

I simply need to send the Tag of top-level parent and the Tag of control itself to my converter class.


Solution

  • The ConverterParameter property can not be bound because it is not a dependency property.

    Since Binding is not derived from DependencyObject none of its properties can be dependency properties. As a consequence, a Binding can never be the target object of another Binding.

    There is however an alternative solution. You could use a MultiBinding with a multi-value converter instead of a normal Binding:

    <Style TargetType="FrameworkElement">
        <Setter Property="Visibility">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource AccessLevelToVisibilityConverter}">
                    <Binding Path="Tag" RelativeSource="{RelativeSource Mode=FindAncestor,
                                                         AncestorType=UserControl}"/>
                    <Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}"/>
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
    

    The multi-value converter gets an array of source values as input:

    public class AccessLevelToVisibilityConverter : IMultiValueConverter
    {
        public object Convert(
            object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return values.All(v => (v is bool && (bool)v))
                ? Visibility.Visible
                : Visibility.Hidden;
        }
    
        public object[] ConvertBack(
            object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }