Common Boolean Converter

I have the following converter

  [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" />

Is there a way to make it more general, i.e. can it return any type of object?

+5
source share
2 answers

You just create TrueValue and FalseValue of type Object. You can update the Equals code to see if IComparable objects are implemented .

[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;
    }
}

To use this, you need to explicitly define the values ​​now:

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

EDIT:

The general version will look like this:

[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;
    }
}

This is not easy to get from XAML. XAML 2009 has some additional support for generics, but it is mainly for free XAML files (i.e. not compiled).

+3
source

I would just use two classes,

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

""

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

, ConverterParameter, Visible false.

- ConverterParameter, -, .

+1

All Articles