Конвертер связыванияПараметр
Есть ли способ сделать это в 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>
Который выглядит почти как ваше первоначальное предложение