Mobile Zone is brought to you in partnership with:

Den is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

Simple binding for simple (maybe not) Windows Phone applications

02.17.2012
| 3598 views |
  • submit to reddit

If you are working with XAML at any level, you should use binding for any data that you are handling in your application. And if you don't use binding, then you probably should - both for convenience and future compatibility purposes. But that's beyond the point of this article. With many Windows Phone applications that I work on, there is one common thing I noticed - the binding harness is almost always the same, with small modifications adapted to a specific project structure. 

It is composed of the following components:

  • A binding class (the viewmodel, if you wish) - the central binding unit for specific areas of the application.
  • The model -  obviously, the class representation of the data that is being used by the application.
  • The view - the UI, for example - a PhoneApplicationPage instance. 

Hey, isn't this the basic structure for MVVM? Indeed, it is. What I noticed, however, is that a lot of developers often jump to using third-party libraries that organize the basic binding for them without the need to do the "plumbing." But is it always necessary? From my own experience, I know that third-party libraries might come at a great performance cost when used in places where those are not necessary. MVVM DLLs might not be that bad, but why import an additional assembly with a lot of dead weight if only basic binding capabilities are required?

Enough talking, let's take a look at the code. First, let's look at what the main binding bridge is:

using System;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace BindingHarness
{
    public class BindingCentral : INotifyPropertyChanged
    {

        static BindingCentral instance = null;
        static readonly object padlock = new object();

        public BindingCentral()
        {
            if (NewLinks == null)
                NewLinks = new ObservableCollection<Link>();
        }

        public static BindingCentral Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new BindingCentral();
                    }
                    return instance;
                }
            }
        }

        private ObservableCollection<string> _newLinks;
        public ObservableCollection<string> NewLinks
        {
            get
            {
                return _newLinks;
            }
            set
            {
                if (_newLinks != value)
                {
                    _newLinks = value;
                    NotifyPropertyChanged("NewLinks");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
               System.Windows.Deployment.Current.Dispatcher.BeginInvoke(
                   () => 
                   { 
                       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
                   });
            }
        }
    }
}

First of all, you might notice that this class follows the singleton pattern, described by Jon Skeet here. Simplistic, yet thread-safe. You probably know that when you create references to static classes in XAML, it is really easy to access data available through those. With instance-based classes, this problem might add some complications, and that is the reason why there is a static instance available inside the class itself, that proves to be of great help for binding purposes.

BindingCentral implements INotifyPropertyChanged - nothing too complicated here. Whenever a property is changed, the PropertyChanged event is raised, notifying the application that one of the properties that might be bound somewhere (not always the case, of course) is modified and proper updating actions should be taken.

QUESTION: Why am I using System.Windows.Deployment.Current.Dispatcher.BeginInvoke instead of simply calling PropertyChanged?

That is because when bound to a UI element, the binding itself will be processed on the UI thread. Therefore, the update is also manipulated on the UI thread. Without proper cross-thread handling, this will cause an exception. An alternative to this would be using a dispatcher that is already associated with a PhoneApplicationPage instance, although I would not recommend going this way because that creates and extra threading layer that is not necessary.

xmlns:local="clr-namespace:BindingHarness"

In the resources section, I am adding the reference to the actual binding class that I was working with. Notice that nowhere in that declaration am I mentioning the existence of a static instance. 

<Application.Resources>
        <local:BindingCentral x:Key="BindingCentral"></local:BindingCentral>
</Application.Resources>

The use of the Instance property is delegated to the elements that are bound to the actual class. For example, if I have a ListBox that is bound to the ObservableCollection inside BindingCentral, the binding expression will look like this:

<ListBox ItemsSource="{Binding Path=Instance.NewLinks,Source={StaticResource BindingCentral}}">

Congratulations, you now have a very basic MVVM mechanism. It might need serious adjustments depending on the project, but for a lot of tasks where only several collections and properties are used, this is the perfect lightweight solution.

Have a better binding idea without the use of third-party libraries? Share it in the comments below!