Monday, June 7, 2010

Silverlight How To: Convert List to ObservableCollection

I was recently working on a Silverlight project where the service operations returned list of business object and the properties on ViewModel were observable collection. As there was no choice than to loop through items in the list and add them to observable collection, I came up with this generic extension method to alleviate the monotony.

   1:  /// <summary>
   2:  /// Converts a collection to specified collection. For instance, List to ObservableCollection.
   3:  /// </summary>
   4:  /// <typeparam name="T">Type of elements in the collection.</typeparam>
   5:  /// <typeparam name="TCollection">Collection that contains elements from the input sequence.</typeparam>
   6:  /// <param name="collection">Collection to convert from.</param>
   7:  /// <returns>TCollection</returns>
   8:  public static TCollection ToCollection<T, TCollection>(this IEnumerable<T> collection)
   9:      where TCollection : ICollection<T>, new()
  10:  {
  11:      var col = new TCollection();
  12:   
  13:      foreach (var item in collection)
  14:      {
  15:          col.Add(item);
  16:      }
  17:   
  18:      return col;
  19:  }

Because I had to convert to more than one type, for instance SortableObservableCollection<T>, ObservableCollection<T> I decided for a generic implementation.

Friday, June 4, 2010

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.