Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Download Source Code | Run Sample

Articles shows how to use ObservableCollection in combination with an object implementing INotifyPropertyChanged interface to display live data in Silverlight Application.

ObservableCollection is a generic dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed and INotifyPropertyChanged provides PropertyChanged notification to clients when any property value gets changed.

Sample Application in Nutshell

We are going to create a simple Silverlight Application which show DataGrid with user names and their respective scores, we will also create a simple Column Chart to display same user data. We will set ItemSource of both control to the same instance of ObservableCollection and finally we will create timer which will randomly update ObservableCollection by adding new row or updating score for random users.

User Class.

As you can see User Class implements INotifyPropertyChange interface, INotifyPropertyChange defines PropertyChanged Event which notifies subscriber on any change in properties, This is very important if you do not implement INotifyPropertyChange interface then any change in your property will not trigger updates in either datagrid and chart.

public class  User : INotifyPropertyChanged{
    
private string  name ;

    public string 
Name{
        
get  return  name }
        
set  {
            
if  ( value  ! name){
                name 
= value;
                
onPropertyChanged( this "Name" ) ;
            
}
        }
    }

    
private long  score ;

    public long 
Score{
        
get  return  score }
        
set  {
            
if  (score ! = value ) {
                score 
= value;
                
onPropertyChanged( this "Score" ) ;
            
}
        }
    }

    
#region  INotifyPropertyChanged Members

    
public event  PropertyChangedEventHandler PropertyChanged ;

    private void 
onPropertyChanged( object  sender
        , 
string  propertyName){

        
if  ( this .PropertyChanged ! = null ){
            PropertyChanged(sender, 
                
new  PropertyChangedEventArgs(propertyName)) ;
        
}
    }

    
#endregion
}

Observable Collection of User

As I mentioned earlier ObservableCollection implements INotifyCollectionChanged interface which defines CollectionChanged event which notifies subscribers on any change in collection, Unless you use ObservableCollection or custom class which implements INotifyCollectionChanged, updates that you make in collection will not trigger update in either datagrid or chart.

ObservableCollection<User> getUserCollection()
{
    ObservableCollection<User> rVal 
= new  ObservableCollection<User>() ;

    
rVal.Add( new  User { Name  "Tom" , Score  }) ;
    
rVal.Add( new  User { Name  "Sam" , Score  }) ;
    
rVal.Add( new  User { Name  "John" , Score  }) ;
    
rVal.Add( new  User { Name  "Dave" , Score  }) ;
    
rVal.Add( new  User { Name  "Sue" , Score  }) ;

    return 
rVal ;
}


XAML Layout and Databinding.

We have a very simple XAML layout which includes DataGrid in top and Charting Control in bottom, Charting control has one ColumnSeries without any data.

< Grid  x:Name ="LayoutRoot"  Background ="White">
        
< Grid.RowDefinitions >
            
< RowDefinition  Height ="*"   />
            <
RowDefinition  Height ="300"   />
        </
Grid.RowDefinitions >
        
< data:DataGrid  x:Name ="dataGrid"  Grid.Row ="0"   >      
        
</ data:DataGrid >

        
< charting:Chart  x:Name ="chartControl"  Grid.Row ="1"  Title ="Live Chart">
            
< charting:Chart.Series >
                
< charting:ColumnSeries  DependentValueBinding ="{Binding Score}"
                                    IndependentValueBinding
="{Binding Name}"   />
            </
charting:Chart.Series >
        
</ charting:Chart >
 
</ Grid >

We will use constructor to bind our data to datagrid and chart, we are also creating a timer which starts after 10 seconds and ticks every 2 second, we are going to randomly change data and add or remove row in collection whenever timer event fires.

ObservableCollection<User> users ;
 
Timer timer ;
        
 public 
Page()  {
            InitializeComponent()
;

            
users  getUserCollection() ;

            this
.dataGrid.ItemsSource  users ;

            
((DynamicSingleSeriesWithAxes) this .chartControl.Series[ 0 ]).ItemsSource  users ;

            
timer  = new  Timer(timerFired, null , 10000 , 5000 ) ;           
 
}


Updating Data

Very important thing to note here is the way in which we have to make updates to our datasource when we are not in UI thread, if you are familiar with Winforms development then you should be familiar with cross-thread access exception when you try to update UI element from another thread. Similar to windows development you will have to use BeginInvoke to make any updates to UI Element or In our case object which can trigger change in UI Element.

void  timerFired( object  state){
    
this .Dispatcher.BeginInvoke( delegate (){
        Random rnd 
= new  Random() ;
        
users[rnd.Next( 0 ,users.Count)].Score  rnd.Next( 1 5 ) ;

        if 
(rnd.Next( 1 5 ) >  3 ) {
            
if  (users.Count >  4 ){
                users.RemoveAt(
4 ) ;
            
else  {
                users.Add(
new  User { Name  "Sue" , Score  }) ;
            
}
        }
    })
;
 
}

We are randomly selecting a row in collection and updating its score, along with that we are also randomly adding or removing row from the collection. Although we are not rebinding our data with DataGrid or Chart they both with immediately get updated whenever source changes.


Closing Notes

You also get two way binding with INotifyPropertyChanged and DataGrid without adding single line of additional code, if you update Score or Name in DataGrid change will immediately trigger in change Chart Control.

Published Sunday, November 2, 2008 10:51 AM by jigar

Comments

# re: Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Monday, November 3, 2008 2:48 AM by kamii47

Wow,

 Nice Sample.Is there any way we do it without timer time interval.

 Mean as data changes in database it will be directly reflected ?

# re: Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Wednesday, November 26, 2008 8:55 AM by raag

hi,

Is there way to show the values and legend text on bar control itself.

Regards

Raag

# re: Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Wednesday, March 25, 2009 3:08 PM by Vineet

Can we do something similer for work flow charts also?

# re: Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Friday, December 18, 2009 1:30 PM by kjartan93

If the DataGrid is bound to a PagedCollectionView rather than an ObservableCollection, what is the expression to use in timerFired( ) to perform the update?

# re: Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Tuesday, November 27, 2012 12:08 AM by Zeeshan

A very good article. I am new to silverlight if you have any video tutorials for beginners than kindly let me know i will be very thankful to you. My email address us

Thanking you.

# re: Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Wednesday, January 30, 2013 12:33 PM by Soni

Nice! An old code but showed just what I wanted!

Thanks

# re: Display Live Data In Silverlight Using ObservableCollection and INotifyPropertyChanged

Tuesday, March 19, 2013 8:31 PM by Donnell

Thanks for sharing your thoughts on ASP.Net. Regards