Windows Presentation Foundation's ObservableCollection Made Easy

Introduction

ObservableCollection represents a dynamic data collection that provides an observable notification about the addition or removal of items to the collection.

ObservableCollection is not a replacement for the List, BindingList or Collection classes. It is a variant that has an additional feature. WPF offers this useful class through the System.ComponentModel namespace.

Bindings done to ListBox or a ListView would have to be bound to collections that implement the INotifyCollectionChanged interface. And its CollectionChanged event would intimate the UI of the underlying changes in the collection. Taking this one step ahead is the concept of ObservationCollection. WPF provides this useful class that already implements the INotifyCollectionChanged and the INotifyPropertyChanged interfaces. So when you bind the UI Controls such as ListBox, or a ListView to an ObservableCollection, the controls will be updated with the changes done to the ObservableCollection.

As expected it provides the two events - CollectionChanged and the PropertyChanged.

An important excerpt from MSDN talks about the XAML usage of this object.

"ObservableCollection<T> can be used as a XAML object element in Windows Presentation Foundation (WPF), in versions 3.0 and 3.5. However, the usage has substantial limitations.

  • ObservableCollection<t> must be the root element, because the x:TypeArguments attribute that must be used to specify the constrained type of the generic ObservableCollection<t> is only supported on the object element for the root element.
  • You must declare an x:Class attribute (which entails that the build action for this XAML file must be Page or some other build action that compiles the XAML).
  • ObservableCollection<t> is in a namespace and assembly that is not initially mapped to the default XML namespace. You must map a prefix for the namespace and assembly, and then use that prefix on the object element tag for ObservableCollection.

A more straightforward way to use ObservableCollection<t> capabilities from XAML in an application is to declare your own non-generic custom collection class that derives from ObservableCollection<t>, and constrains it to a specific type. Then map the assembly that contains this class, and reference it as an object element in your XAML."

ObservableCollection - Class Hierarchy

This is the class hierarchy for the ObservableCollection class.

Class hierarchy for the ObservableCollection class
Figure 1

The CollectionChanged and the PropertyChanged events of the ObservableCollection class make it a strong candidate over regular collection objects. The BeginUpdate and the EndUpdate methods pass the NotifyCollectionChangedEventArgs with the changes to the appropriate events.

ObservableCollection - Definition

ObservationCollection is defined as follows:

  public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged

As you can see, it derives from the Collection<t> class and implements the INotifyCollectionChanged and the INotifyPropertyChanged events.

You can bind the content of the ObservableCollection to any panel, by using the ItemsControl and the ItemsPanelTemplate property.

Good sample codes for usage of ObservableCollections can be found at various places on the holy internet. A few worth mentioning include the MSDN page and the article on "SwitchOnTheCode". You can find the link to both these articles at the end of this article.

Binding ObservableCollection

You can bind an ObservableCollection in code-behind or XAML. Look for the samples below:

  //Create an ObservableCollection
  public ObservableCollection myFirstObservableCollection = new ObservableCollection();
  
  //Fill it up.
  foreach (var item in enumerableList)
  {
      myFirstObservableCollection.Add(item);
  }
  
  //Associate it with the control's ItemSource property
   myControl.ItemsSource = myFirstObservableCollection;
Code Behind



  <ControlName ItemSource="{Binding myFirstObservableCollection } />
XAML Code





Windows Presentation Foundation's ObservableCollection Made Easy

Sorting An ObservableCollection

To sort an ObservableCollection<T> you can use lambda expressions. The following sample code shows you to sort the ObservableCollection 'myCollection' by the field id.

  observablecollection<myobject> mycollection = new observablecollection< myobject >(o.orderby(o => o.id));

However, the linq orderby gives you an iorderedenumerable object, which would mean that you have to re-bind the data to the control. instead, we can write our sorting mechanism. one such sample that i found on the web is from brian lagunas's website. this code is as-is from the website.

  public class SortableObservableCollection<T> : ObservableCollection<T>
  {
    public SortableObservableCollection(List<T> list)
       : base(list)
    {
    }
  
    public SortableObservableCollection(IEnumerable<T> collection)
       : base(collection)
    {
    }
  
    public void Sort<TKey>(Func<T, TKey> keySelector, System.ComponentModel.ListSortDirection direction)
    {
       switch (direction)
       {
          case System.ComponentModel.ListSortDirection.Ascending:
             {
                ApplySort(Items.OrderBy(keySelector));
                break;
             }
          case System.ComponentModel.ListSortDirection.Descending:
             {
                ApplySort(Items.OrderByDescending(keySelector));
                break;
             }
       }
    }
  
    public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
    {
       ApplySort(Items.OrderBy(keySelector, comparer));
    }
  
    private void ApplySort(IEnumerable<T> sortedItems)
    {
       var sortedItemsList = sortedItems.ToList();
  
       foreach (var item in sortedItemsList)
       {
          Move(IndexOf(item), sortedItemsList.IndexOf(item));
       }
    }
  }

  //sort ascending
  MySortableList.Sort(x => x.Name, ListSortDirection.Ascending);
  
  //sort descending
  MySortableList.Sort(x => x.Name, ListSortDirection.Descending);

Extension Method ToObservableCollection

And finally an extension method. Here is an extension method that I use to convert an IEnumerable object to an ObservableCollection.

public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerableList)

{ var ObservableCollection = default(ObservableCollection<T>()); if (null != enumerableList ) {            var observableCollection = new ObservableCollection<T>(); foreach (var item in enumerableList)                observableCollection.Add(item);        } return ObservableCollection; }

I hope this article gave you some insight into ObservableCollection. There are many websites with great code samples that show how ObservableCollections works. Please refer to the References section below for more samples.

References

MSDN intro on ObservableCollection<T> class
SwitchOnTheCode
Sortable ObservableCollection for WPF

Related Articles





About the Author

Srinath M S

I would love to leave a footprint in this flat world

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Hundreds of millions of users have adopted public cloud storage solutions to satisfy their Private Online File Sharing and Collaboration (OFS) needs. With new headlines on cloud privacy issues appearing almost daily, the need to explore private alternatives has never been stronger. Join ESG Senior Analyst Terri McClure and Connected Data in this on-demand webinar to take a look at the business drivers behind OFS adoption, how organizations can benefit from on-premise deployments, and emerging private OFS …

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

Most Popular Programming Stories

More for Developers

RSS Feeds