开发者

A generic Boolean Convertor

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 generic, ie it can return any type of object?


You just make TrueValue and FalseValue of type Object. You may want to update the Equals code to see if the objects implement IComparable as well though.

[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'd need to explicitly define the values now though:

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

EDIT:

A generic version would 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 isn't easily accessible from XAML though. XAML 2009 has some additional support for generics, but that is mostly for loose XAML files (i.e. not compiled).


I would simply use two classes,

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

Or I will pass a converter parameter called "inverse"

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

You can then check inverse being passed in ConverterParameter and return Visible on false.

You can pass anything on ConverterParameter or it can also be bound to something that can control your logic.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜