Windows Phone 7 Databinding - Painting and Redrawing Performance with the ObservableCollection

14 June 2011

I’ve been playing around with observable collections, as you do, and appear to have come up with what seems to be a pattern for binding data to the View which appears to get pretty good responsiveness and performance.

Many blog posts I found talked about using ObservableCollections on the ViewModel with automatic properties, and ensure that in the constructor of the class the collection is in, we simply set it to an empty collection as follows:

public MyViewModel()
{
this.MyCollection = new ObservableCollection<T>();
}

public ObservableCollection<MyThing> MyCollection {get;set;}

The reasoning given for this is that it’s not necessary to have a property change event fired on the collection itself, just on changes to it. However, I gained better performance by setting the collection’s value directly initially when ‘painting’ to the screen, that is the initial render of say a listbox. You may notice a small but noticeable delay even with small lists when adding items to an existing collection on the initial draw.

So, the recommendation is to make ObservableCollection a ‘normal’ property with a backing private member variable. Also implement property change notification on them so that when we set the collection property the View is updated accordingly (normally done once on load), something familiar like this:

        public ObservableCollection<MyThing> MyCollection 
        {
            get
            {
                return _myCollection;
            }
            set
            {
                _myCollection= value;
                base.NotifyOfPropertyChange(() => MyCollection );
            }
        }

So, in our View Model we can set the value of the collection directly on initial loading of the page. Another important tip is to always wrap this call inside a Dispatcher.BeginInvoke, regardless of what thread you are on. The reasoning for this is that we want to queue the binding asynchronously on the UI thread. If you don’t do this, you can notice a slight blocking effect as the page draws. With the Dispatcher call, the page appears to load faster than without the call. The UI effect of using the Dispatcher can be that instead of blocking or pausing on the redraw, elements will load instantly or ‘stream’ in quickly into the listbox instead of a ‘pause…. appear’ type delivery to the screen.

Dispatcher.BeginInvoke(() => this.MyCollection = myCollection;);

The initial drawing of the page is a particular use case, this approach allows us to get the databinding done as quickly as possible whilst having the UI appear as responsive as it can.

When redrawing the page’s data, perhaps after a synchronisation call to a service, we have a slightly different use case. Here, we dont’ want to assign to the collection we want to replace it seamlessly so that primarily it doesn’t flicker and has with minimal impact on the user experience. This is how i’ve been doing that:

Dispatcher.BeginInvoke(() => this.MyCollection.ReplaceRange(myNewCollection););

ReplaceRange is a simple extension method shown below which will clear the existing list and then add all the new items. This does take a little longer than reassignment, but looks much better when there’s existing data on screen requiring an update.

        /// <summary> 
        /// Clears collection and replaces it with the provided collection. 
        /// </summary> 
        public void ReplaceRange(IEnumerable<T> sourceItems) 
        {
            this.Clear();
            foreach (var sourceItem in sourceItems)
            {
                this.Add(sourceItem);
            }
        }

This appears to be a good way to redraw or refresh existing data that is say presented within a ListBox. Note again the call to the Dispatcher to have the update performed asynchronously on the UI thread to get that responsiveness feel. It’s worth noting that we’re not talking about thousands of items here, that’s not the use case. It might be 10-50 items that you want to update seamlessly with no flickering.

In summary, it’s not the most elegant of code that’s for sure, but there are different use cases for how data should be placed onto the screen (e.g fresh data paint or updating data redraw) and this affects the way we can and should use databinding to best effect. This is what I’ve come up with some tinkering, would love to hear from people who have tried other approaches on the phone to get maximum responsiveness.

Want to get started?

We would love to help with your next app or game, please do get in touch.