Thursday, November 17, 2011

Detecting Changes

Silverlight has the capability to update the UI when the underlying model changes. For example, if we are displaying the total number of hours worked by an employee, and we change an employee’s TotalHours property, the UI will automatically update to reflect the new total. For this to work we need our model objects to implement a magic interface.

For collections this magic interface is the INotifyCollectionChanged interface.

Fortunately, there is already a collection class we can use that implements INotifyCollectionChanged – this is ObservableCollection. When you add or remove objects to an observable collection, the observable collection will automatically raise a CollectionChanged event. When Silverlight establishes a data binding it will look to see if the model collection implements the INotifyCollectionChanged interface and if so will automatically subscribe to the event. This means you don’t have any additional work to do when binding to an observable collection. If we bind an observable collection to the ItemsSource property of a ListBox, for example, then the ListBox will automatically display new objects we add to the collection, and will automatically remove objects we delete from the collection.

For non-collections the magic interface is the INotifyPropertyChanged interface. This interface demands that an object implement a PropertyChanged event. A typical implementation is shown below.

public class Employee : INotifyPropertyChanged {     string _name;     public string Name     {         get { return _name; }         set          {             if (_name != value)             {                 _name = value;                 RaisePropertyChanged("Name");             }         }     }      int _departmentID;     public int DepartmentID     {         get { return _departmentID; }         set         {             if (_departmentID != value)             {                 _departmentID = value;                 RaisePropertyChanged("DepartmentID");             }         }     }      public event PropertyChangedEventHandler PropertyChanged;      void RaisePropertyChanged(string propertyName)     {         var handler = PropertyChanged;         if (handler != null)         {             handler(this, new PropertyChangedEventArgs(propertyName));         }     }                } 

All we need to do is raise the PropertyChanged event while passing along the name of the property that changed as an event argument. Silverlight will automatically subscribe to this event when it binds to an object that implements INotifyPropertyChanged. When we make changes to the underlying object the changes will be reflected immediately in the UI.

1 comment: