首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >绑定ConverterParameter

绑定ConverterParameter
EN

Stack Overflow用户
提问于 2013-03-09 17:07:59
回答 3查看 162.9K关注 0票数 178

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-09 18:48:27

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

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

然而,还有另一种解决方案。您可以使用带有multi-value converterMultiBinding,而不是普通绑定:

<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();
    }
}
票数 333
EN

Stack Overflow用户

发布于 2013-03-09 18:47:11

不,不幸的是,这是不可能的,因为ConverterParameter不是DependencyProperty,所以您不能使用绑定

但是也许你可以欺骗并使用一个带有IMultiValueConverterMultiBinding来传递2个Tag属性。

票数 36
EN

Stack Overflow用户

发布于 2019-01-17 01:10:16

为了将Binding用于ConverterParameter,还有一种使用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>
[ContentProperty(nameof(Binding))]
public class ConverterBindableParameter : MarkupExtension
{
    #region Public Properties

    public Binding Binding { get; set; }
    public BindingMode Mode { get; set; }
    public IValueConverter Converter { get; set; }
    public Binding ConverterParameter { get; set; }

    #endregion

    public ConverterBindableParameter()
    { }

    public ConverterBindableParameter(string path)
    {
        Binding = new Binding(path);
    }

    public ConverterBindableParameter(Binding binding)
    {
        Binding = binding;
    }

    #region Overridden Methods

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var multiBinding = new MultiBinding();
        Binding.Mode = Mode;
        multiBinding.Bindings.Add(Binding);
        if (ConverterParameter != null)
        {
            ConverterParameter.Mode = BindingMode.OneWay;
            multiBinding.Bindings.Add(ConverterParameter);
        }
        var adapter = new MultiValueConverterAdapter
        {
            Converter = Converter
        };
        multiBinding.Converter = adapter;
        return multiBinding.ProvideValue(serviceProvider);
    }

    #endregion

    [ContentProperty(nameof(Converter))]
    private class MultiValueConverterAdapter : IMultiValueConverter
    {
        public IValueConverter Converter { get; set; }

        private object lastParameter;

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (Converter == null) return values[0]; // Required for VS design-time
            if (values.Length > 1) lastParameter = values[1];
            return Converter.Convert(values[0], targetType, lastParameter, culture);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            if (Converter == null) return new object[] { value }; // Required for VS design-time

            return new object[] { Converter.ConvertBack(value, targetTypes[0], lastParameter, culture) };
        }
    }
}

在代码库中有了这个MarkupExtension,您就可以通过以下方式简单地绑定ConverterParameter

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

这看起来和你最初的提议很像。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15309008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档