绑定ConverterParameter

时间:2013-03-09 09:07:59

标签: wpf xaml styles

我有没有办法在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发送到我的转换器类。

3 个答案:

答案 0 :(得分:266)

ConverterParameter属性无法绑定,因为它不是依赖项属性。

由于Binding不是从DependencyObject派生的,因此其属性都不能是依赖属性。因此,绑定永远不会成为另一个绑定的目标对象。

然而,有另一种解决方案。您可以使用MultiBinding multi-value converter代替普通绑定:

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

答案 1 :(得分:33)

不,不幸的是,这是不可能的,因为ConverterParameter不是DependencyProperty所以你将无法使用绑定

但也许你可以欺骗并使用MultiBinding IMultiValueConverter来传递2 Tag个属性。

答案 2 :(得分:5)

还有另一种使用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
}

在代码库中使用此扩展,您可以通过以下方式简单地绑定Converter参数:

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

看起来像您最初的建议