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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With