Saturday, May 29, 2010

Silverlight How To: Bind control to inverse of Boolean property value

I recently had to bind a control's visibility to inverse of a Boolean property value. I implemented following converter to achieve it.

   1:  public class BoolToVisibilityConverter : IValueConverter
   2:  {
   3:   
   4:      #region IValueConverter Members
   5:   
   6:      // This method is called when the value from the property is propagated to the control.
   7:      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   8:      {
   9:          if (!(value is bool) || targetType != typeof(Visibility))
  10:              return false;
  11:          if (parameter == null)
  12:              return (bool)value ? Visibility.Visible : Visibility.Collapsed;
  13:          if (parameter is string && parameter.ToString() == "Inverse")
  14:              return (bool)value ? Visibility.Collapsed : Visibility.Visible;
  15:          return false;
  16:      }
  17:   
  18:      // This method is called the value from the control is propagated to the property. 
  19:      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  20:      {
  21:          if (!(value is Visibility) || targetType != typeof(bool))
  22:              return false;
  23:          if (parameter == null)
  24:              return (Visibility)value == Visibility.Visible ? true : false;
  25:          if (parameter is string && parameter.ToString() == "Inverse")
  26:              return (Visibility)value == Visibility.Visible ? false : true;
  27:          return false;
  28:      }
  29:   
  30:      #endregion
  31:  }

Next add namespace to root XAML node

   1:  xmlns:converter="clr-namespace:yournamespace"

Then add converter class as a resource to XAML control

   1:  <UserControl.Resources>
   2:      <converter:BoolToVisibilityConverter x:Key="visibilityConverter" />
   3:  </UserControl.Resources>

And finally add data binding passing "Inverse" parameter value

   1:  <Button Content="MyButton" x:Name="MyButton" Visibility="{Binding YourProperty, Mode=TwoWay, Converter={StaticResource visibilityConverter}, ConverterParameter=Inverse}"/>

There could be multitude of IValueConverter implementations, perhaps better than this. This is what I came up with to get me going. Please feel free to comment and suggest.