有什么办法可以“反转”转换器吗?

时间:2019-10-23 09:15:04

标签: wpf

在WPF中,可以在绑定中使用转换器,以便可以将控件的Visibility属性绑定到视图模型中的Boolean属性。

对于这种特定的配对(VisibilityBoolean),WPF确实提供了一个名为BooleanToVisibilityConverter的即用型转换器。

但是,假设我想将控件的Boolean属性绑定到视图模型中的Visibility属性。有没有办法使用标准的BooleanToVisibilityConverter并告诉绑定将其反转(在ConvertBack上使用Convert代替,反之亦然)?

还是我需要为这种情况编写另一个转换器?

2 个答案:

答案 0 :(得分:2)

因此,没有内置的转换器反相方法。但是,我们可以通过引入像这样的“ shim”转换器来解决此问题:

public class InverterConverter : IValueConverter
{
    public IValueConverter Converter { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Converter.ConvertBack(value, targetType, parameter, culture);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Converter.Convert(value, targetType, parameter, culture);
    }
}

用法如下:

<ContentControl>
    <ContentControl.Content>
        <Binding>
            <Binding.Converter>
                <InverterConverter Converter="{StaticResource YourConverter}" />
            </Binding.Converter>
        </Binding>
    </ContentControl.Content>
</ContentControl> 

这显然是一些繁重的语法,但是我们可以通过这个小的标记扩展来简化它:

public class InvertedExtension : MarkupExtension
{
    public IValueConverter Converter { get; set; }

    public InvertedExtension(IValueConverter converter)
    {
        Converter = new InverterConverter() { Converter = converter };
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return Converter;
    }
}
<ContentControl Content="{Binding Converter={Inverted {StaticResource MyConverter}}}" />

答案 1 :(得分:1)

  

有什么方法可以使用标准BooleanToVisibilityConverter并告诉绑定将其反转(改为在ConvertBack上使用Convert,反之亦然)?

否。

  

还是我需要为这种情况编写另一个转换器?

是的。

您可以实现一个通用转换器,该转换器接受任何类型的“ true”和“ false”值:

public class BooleanConverter<T> : IValueConverter
{
    public T True { get; set; }
    public T False { get; set; }

    public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
        value is bool && ((bool)value) ? True : False;

    public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
        value is T && EqualityComparer<T>.Default.Equals((T)value, True);
}

...并从中派生出您要处理的每种类型:

public class BooleanToVisibilityNegationConverter : BooleanConverter<Visibility>
{
    public BooleanToVisibilityNegationConverter()
        : base()
    {
        True = Visibility.Hidden;
        False = Visibility.Visible;
    }
}