How do I invert BooleanToVisibilityConverter?
I'm using a BooleanToVisibilityConverter
in WPF to bind the Visibility
property of a control to a Boolean
. This works fine, but I'd like one of the controls to hide if the boolean is true
, and show if it's false
.
Instead of inverting, you can achieve the same goal by using a generic IValueConverter
implementation that can convert a Boolean value to configurable target values for true and false. Below is one such implementation:
public class BooleanConverter<T> : IValueConverter
{
public BooleanConverter(T trueValue, T falseValue)
{
True = trueValue;
False = falseValue;
}
public T True { get; set; }
public T False { get; set; }
public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is bool && ((bool) value) ? True : False;
}
public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is T && EqualityComparer<T>.Default.Equals((T) value, True);
}
}
Next, subclass it where T
is Visibility
:
public sealed class BooleanToVisibilityConverter : BooleanConverter<Visibility>
{
public BooleanToVisibilityConverter() :
base(Visibility.Visible, Visibility.Collapsed) {}
}
Finally, this is how you could use BooleanToVisibilityConverter
above in XAML and configure it to, for example, use Collapsed
for true and Visible
for false:
<Application.Resources>
<app:BooleanToVisibilityConverter
x:Key="BooleanToVisibilityConverter"
True="Collapsed"
False="Visible" />
</Application.Resources>
This inversion is useful when you want to bind to a Boolean property named IsHidden
as opposed IsVisible
.
Write your own is the best solution for now. Here is an example of a Converter that can do both way Normal and Inverted. If you have any problems with this just ask.
[ValueConversion(typeof(bool), typeof(Visibility))]
public class InvertableBooleanToVisibilityConverter : IValueConverter
{
enum Parameters
{
Normal, Inverted
}
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
var boolValue = (bool)value;
var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter);
if(direction == Parameters.Inverted)
return !boolValue? Visibility.Visible : Visibility.Collapsed;
return boolValue? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
<UserControl.Resources>
<Converters:InvertableBooleanToVisibilityConverter x:Key="_Converter"/>
</UserControl.Resources>
<Button Visibility="{Binding IsRunning, Converter={StaticResource _Converter}, ConverterParameter=Inverted}">Start</Button>
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
public sealed class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var flag = false;
if (value is bool)
{
flag = (bool)value;
}
else if (value is bool?)
{
var nullable = (bool?)value;
flag = nullable.GetValueOrDefault();
}
if (parameter != null)
{
if (bool.Parse((string)parameter))
{
flag = !flag;
}
}
if (flag)
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
if (parameter != null)
{
if ((bool)parameter)
{
back = !back;
}
}
return back;
}
}
and then pass a true or false as the ConverterParameter
<Grid.Visibility>
<Binding Path="IsYesNoButtonSetVisible" Converter="{StaticResource booleanToVisibilityConverter}" ConverterParameter="true"/>
</Grid.Visibility>