Parametrized BooleanToVisibilityConverter

By Mirek on (tags: BooleanToVisibilityConverter, IValueConverter, WPF, categories: code)

Windows Presentation Foundation allows us to create our own value converters and use them in XAML bindings. WPF also comes with a set of predefined converters. One of them is BooleanToVisibilityConverter. It this post I will show you how to create own version of this converter with parameter feature supported.

BoleanToVisibilityConverter sets the Visibility value to Visible when input value is true and to Collapsed when input value is false. So having IsVisible boolean property on attached data context we can hide or show the button depending on the value of this property

   1: <Button Content="Start" 
   2:         Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />

where we use static resource which is an instance of BoleanToVisibilityConverter declared in resources as follows

   1: <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />

That’s simple.

Now what if we would like to modify the converter the way that it for some cases reverse the input value. For instance we want to have another button which will be visible when the IsVisible property value is false. The ConverterParameter property comes with help. When you take a look on IValueConverter interface, which all value converters must implement, there is a parameter parameter in Convert method

   1: object Convert(object value, Type targetType, object parameter, CultureInfo culture);

which we would like to use to pass a parameter to our converter. Let’s say when we pass the value “false” as parameter then the converter interprets the input boolean value as reverse value, for true false and for false true. To do that we have to create new value converter which will have the same logic as built in BooleanToVisibilityConverter. Let’s call it ParametrizedBooleanToVisibilityConverter

   1: public sealed class ParametrizedBooleanToVisibilityConverter : IValueConverter
   2: {
   3:    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   4:    {
   5:        bool flag = false;
   6:        if (value is bool)
   7:        {
   8:            flag = (bool)value;
   9:        }
  10:        else
  11:        {
  12:            if (value is bool?)
  13:            {
  14:                bool? flag2 = (bool?)value;
  15:                flag = (flag2.HasValue && flag2.Value);
  16:            }
  17:        }
  18:  
  19:        //if false is passed as a converter parameter then reverse the value of input value
  20:        if (parameter != null)
  21:        {
  22:            bool par = true;
  23:            if ((bool.TryParse(parameter.ToString(), out par)) && (!par)) flag = !flag;
  24:        }                
  25:  
  26:        return flag ? Visibility.Visible : Visibility.Collapsed;
  27:    }
  28:  
  29:    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  30:    {
  31:        if (value is Visibility)
  32:        {
  33:            return (Visibility)value == Visibility.Visible;
  34:        }
  35:        return false;
  36:    }
  37:    
  38:    public ParametrizedBooleanToVisibilityConverter()
  39:    {
  40:    }
  41: }

The whole class body was copied from built in converter. The only new lines are 19 to 24 where the parameter is parsed and when equals boolean false then the input value is reversed. Now we can have two buttons which are alternately visible depending on the value of binded property.
   1: <Button Content="Start" Visibility="{Binding IsVisible, 
   2:                         Converter={StaticResource BoolToVisParamConverter}}" />
   3: <Button Content="Stop" Visibility="{Binding IsVisible, 
   4:                        Converter={StaticResource BoolToVisParamConverter}, 
   5:                        ConverterParameter=false}" />

where our new converter is declared as a static resource

   1: <local:ParametrizedBooleanToVisibilityConverter x:Key="BoolToVisParamConverter" />

When IsVisible is set to true then Start button is visible otherwise the Stop button is visible. Buttons are displayed at the same position in the layout because the converter sets the Visibility to Collapsed which causes the rendering logic to not reserve the space for not visible button.

We could extend this converter by adding support for Hidden Visibility mode. Basically the value passed as a converter parameter is by default passed as string so we can construct any string and then parse it in the Convert method.

Cheers