你能在xaml中的属性绑定上调用多个转换器吗?如果是的话,如何调用

时间:2015-11-23 12:44:59

标签: c# wpf vb.net xaml converter

我在xaml中定义了一个按钮,其可见性使用标准的BooleanToVisibility转换器绑定到依赖项属性,如此。

 Visibility="{Binding Path=GoToButtonVisibility,Converter={StaticResource booltovis}, RelativeSource={RelativeSource TemplatedParent}}"

现在我还有一个文本框,其只读属性我想绑定到我上面提到的按钮的可见性,除了它需要相反,所以如果按钮不可见,它只读将是是的,如果不是,它将是假的。

这意味着我需要某种方式在我的xaml中使用Not x。使用this回答堆栈溢出救援。

所以现在我有一个很好的NotConverter,但我不能简单地做这样的事情;

 IsReadOnly="{Binding ElementName=PART_GoToButton, Path=Visibility, Converter={StaticResource NotConverter}}"

因为NotConverter会抛出一个无效的强制转换异常。我没有问题,我理解为什么。但我喜欢非转换器的原理,所以我的问题如下。

1)在xaml本身中,可以同时调用两个转换器,以便它们产生所需的结果。 2)假设1是不可能的,那么它表明需要对布尔转换器的可见性。由于内置了BooleanToVisibility转换器,我不确定如何编写转换和转换函数,因此我将如何有效地反转它们。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

使用@Jogy 的回答中描述的聚合转换器,您甚至可以使用以下标记扩展:

[MarkupExtensionReturnType(typeof(IValueConverter))]
public class ConverterChainExtension : MarkupExtension
{
    public ConverterChainExtension()
    {
    }

    public ConverterChainExtension(string converterNames)
    {
        this.ConverterNames = converterNames;
    }

    public string Separator { get; set; }

    [ConstructorArgument("converterNames")]
    public string ConverterNames { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        List<IValueConverter> converters = new List<IValueConverter>();
        if (this.ConverterNames != null)
        {
            foreach (string converterName in this.ConverterNames.Split(new[] { this.Separator }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (new StaticResourceExtension(converterName).ProvideValue(serviceProvider) is IValueConverter converter)
                {
                    converters.Add(converter);
                }
                else
                {
                    throw new InvalidOperationException($"Couldn't find the converter with name : '{converterName}'");
                }
            }
        }

        return new YourAggregateConverter(converters);
    }
}

在将您想要的转换器声明为资源(BoolInverterConverterBoolToVisibilityConverter)之后,您可以像这样使用标记扩展:

<Button Visibility="{Binding SomeProperty, Converter={ConverterChain Separator=/, ConverterNames=BoolInverterConverter/BoolToVisibilityConverter}}"/>