通用布尔转换器

时间:2011-04-11 15:44:43

标签: wpf

我有以下转换器

  [ValueConversion(typeof(bool), typeof(Visibility))]
public sealed class BoolToVisibilityConverter : IValueConverter
{
    public Visibility TrueValue { get; set; }
    public Visibility FalseValue { get; set; }

    public BoolToVisibilityConverter()
    {
        // set defaults
        TrueValue = Visibility.Visible;
        FalseValue = Visibility.Collapsed;
    }

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (!(value is bool))
            return null;
        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (Equals(value, TrueValue))
            return true;
        if (Equals(value, FalseValue))
            return false;
        return null;
    }
}
<conv:BoolConverter x:Key="enableStyleConvertor" TrueValue="Visible" FalseValue="Collapsed" />

有没有办法让它更通用,即它可以返回任何类型的对象?

2 个答案:

答案 0 :(得分:3)

您只需创建Object类型的TrueValue和FalseValue。您可能希望更新Equals代码以查看对象是否也实现了IComparable

[ValueConversion(typeof(bool), typeof(object))]
public sealed class MyConverter : IValueConverter
{
    public object TrueValue { get; set; }
    public object FalseValue { get; set; }

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (!(value is bool))
            return null;
        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (IsEqual(value, TrueValue))
            return true;
        if (IsEqual(value, FalseValue))
            return false;
        return null;
    }

    private static bool IsEqual(object x, object y) {
        if (Equals(x, y))
          return true;

        IComparable c = x as IComparable;
        if (c != null)
           return (c.CompareTo(y) == 0);

        return false;
    }
}

要使用此功能,您需要现在明确定义值:

<local:MyConverter>
    <local:MyConverter.TrueValue>
        <Visibility>Visible</Visibility>
    </local:MyConverter.TrueValue>
    <local:MyConverter.FalseValue>
        <Visibility>Collapsed</Visibility>
    </local:MyConverter.FalseValue>
</local:MyConverter>

编辑:

通用版本如下所示:

[ValueConversion(typeof(bool), typeof(object))]
public sealed class MyConverter<T> : IValueConverter {
    public T TrueValue { get; set; }
    public T FalseValue { get; set; }

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture) {
        if (!(value is bool))
            return null;
        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture) {
        if (IsEqual(value, TrueValue))
            return true;
        if (IsEqual(value, FalseValue))
            return false;
        return null;
    }

    private static bool IsEqual(object x, object y) {
        if (Equals(x, y))
            return true;

        IComparable c = x as IComparable;
        if (c != null)
            return (c.CompareTo(y) == 0);

        return false;
    }
}

但是XAML无法轻易访问。 XAML 2009有一些additional support用于泛型,但主要用于loose XAML files(即未编译)。

答案 1 :(得分:1)

我只想使用两个类,

BooleanToVisibilityConverter (Visible on true)
OppositeBooleanToVisibilityConverter (Visible on false)

或者我将传递一个名为“inverse”的转换器参数

<Button 
   Visibility="{Binding myValue, 
      Converter={StaticResource booleanToVisibility},
      ConverterParameter=inverse}" />

然后,您可以检查在ConverterParameter中传递的反向并在false时返回Visible。

您可以在ConverterParameter上传递任何内容,也可以绑定到可以控制逻辑的内容。