Fun with List Bindings in Silverlight 2

January 10, 2009
No Comments.

Silverlight Logo
Back in Silverlight 1.0 days I wrote a quick little sample showing off how you could use ASP.NET AJAX Web Services to drive a Silverlight 1.0 app. It was a fun little live graph example (found here). I’ve been wanting to re-do it for Silverlight 2 but I couldn’t find a good reason. After answering a bunch of data binding questions on the Silverlight.NET forums, I had my answer.

I kept seeing the word: “Rebinding”. Huh, I thought. Why are you re-binding anything? Silverlight 2 (and WPF) allow you to have bindings that see changes and notify the control that is bound. This is most effectively used when binding a collection of elements to a control so that as the collection changes, the control shows the changes. I use this when I am doing data binding to a collection that I get from the server so that when I get new results I just change the collection and the UI updates automagically! But how does this work?

This works by supporting the INotifyCollectionChanged interface on a collection. This interface is simple, but in almost every case, I recommend using the ObservableCollection generic collection instead of implementing it your own. You can use this collection in any place you’d normally use a List. This collection simply implements the interface for you so you can add or remove items and the list control will update the UI for you. One unclear fact is that this doesn’t require two-way data binding because you’re pushing changes from the collection to the control (which is only a OneWay binding). A OneTime binding doesn’t work though.

To show how this works, I’ve re-created my chart example. It uses the Chart control from the Silverlight Toolkit to show a simple line chart as shown below:

In this example, I created a simple web service that returns a set of numbers and labels that indicate some data using a MyData class:

public class MyData
  public string Label { get; set; }
  public double Value { get; set; }

The web service just computes a list of data items to be charted (in our case I wanted six sets of data):

public MyData[] GetData()
  const int numLines = 6;
  double rangeSize = 100 / numLines;
  MyData[] points = new MyData[numLines];
  Random rnd = new Random();

  for (var x = 0; x < numLines; ++x)
    // Get the number of seconds since the 
    // start of the day as our label 
    string label = DateTime.Now.TimeOfDay.TotalSeconds.ToString();
    points[x] = new MyData() 
      Label = label, 
      Value = (rnd.NextDouble() * rangeSize) + (x * rangeSize) 
  return points;

In the Silverlight 2 application is the real interesting stuff as I simply create a small set of ObservableCollection structures (one per line of the graph). I create these then bind to them.

I wanted the graph to add new points to each line every two seconds and make sure that only twenty points were shown (so it would be a graph of the last twenty results). Because I was bound using an ObservableCollection, all I needed to do was add the points to the end of the collection and remove points from the start to make sure that it never had more points than needed like so:

int counter = 0;

// Put the new points into the Collections
foreach (MyData point in e.Result)
  // Remove items at the start to limit the results
  while (data[counter].Count >= MAXRESULTS) data[counter].RemoveAt(0);

  // Add the data

This is at the center of most of my data bound implementations as I want the data to affect the bound items and not have to constantly manage the actual data binding of the UI. This is central to allowing a separation of concerns in your Silverlight 2 applications as well as making your life easier as a Silverlight developer.

One of the advantages of this strategy with a typical data-driven Silverlight application is that you can use an instance of an object on your XAML and then data binding in Blend becomes a lot easier instead of having to do all the binding of the data in code. XAML becomes the View…(more on this in an upcoming MSDN article).

Go grab the code and play with it and please let me know what you think.