Конвертер связыванияПараметр

Есть ли способ сделать это в 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>

Мне просто нужно отправить Tag родителя верхнего уровня и Tag самого элемента управления в класс конвертера.

Ответ 1

Свойство ConverterParameter не может быть связано, поскольку оно не является свойством зависимостей.

Так как Binding не является производным от DependencyObject, ни одно из его свойств не может быть зависимыми свойствами. Как следствие, привязка никогда не может быть целевым объектом другого привязки.

Однако существует альтернативное решение. Вы можете использовать MultiBinding с многозначным преобразователем вместо обычного привязки:

<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>

Конвертер с несколькими значениями получает в качестве входных данных массив значений источника:

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();
    }
}

Ответ 2

Нет, к сожалению, это невозможно, потому что ConverterParameter не является DependencyProperty, поэтому вы не сможете использовать привязки

Но, возможно, вы могли бы обмануть и использовать MultiBinding с IMultiValueConverter, чтобы передать свойства 2 Tag.

Ответ 3

Существует также альтернативный способ использования MarkupExtension для использования привязки для параметра преобразователя. С этим решением вы все еще можете использовать IValueConverter по умолчанию вместо IMultiValueConverter, потому что ConverterParameter передается в IValueConverter, как вы и ожидали в первом примере.

Вот мой многоразовый MarkupExtension:

/// <summary>
///     <example>
///         <TextBox>
///             <TextBox.Text>
///                 <wpfAdditions:ConverterBindableParameter Binding="{Binding FirstName}"
///                     Converter="{StaticResource TestValueConverter}"
///                     ConverterParameterBinding="{Binding ConcatSign}" />
///             </TextBox.Text>
///         </TextBox>
///     </example>
/// </summary>
public class ConverterBindableParameter : MarkupExtension
{
    #region Public Properties

    public Binding Binding { get; set; }

    public IValueConverter Converter { get; set; }

    public Binding ConverterParameterBinding { get; set; }

    #endregion

    #region Overridden Methods

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var multiBinding = new MultiBinding();
        multiBinding.Bindings.Add(Binding);
        multiBinding.Bindings.Add(ConverterParameterBinding);
        var adapter = new MultiValueConverterAdapter
                      {
                          Converter = Converter
                      };
        multiBinding.Converter = adapter;
        return multiBinding.ProvideValue(serviceProvider);
    }

    #endregion
}

С этим расширением в вашей кодовой базе вы можете просто привязать параметр преобразователя следующим образом:

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

Который выглядит почти как ваше первоначальное предложение