Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!
Windows Phone Zone is brought to you in partnership with:

Den works on awesome stuff. He is a sophomore in college, a Microsoft MVP, a Microsoft Student Insider, a technical writer for DZone and a contributing author for Coding4Fun on Channel9. He is maintaining a number of open-source projects on CodePlex and GitHub. Den is a DZone Zone Leader and has posted 388 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
Email
Views: 1260
  • submit to reddit
It's so easy to get up and running with your first Windows Phone app!  Just pick up the FREE toolkit from Microsoft, register at AppHub, and start checking out some fundamental tutorials.

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!

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

The Windows Phone Microzone, which is supported by Microsoft, is your one-stop-shop for news, tutorials, perspectives, and research on the mobile platform that is making waves in smartphone ecosystem.