Writing code that sets the properties of user interface controls to the required data is a tried-and-tested technique for wiring a user interface (UI) to a data source, but can result in having to write lengthy and repetitive code to ensure that the UI is correctly synchronized.

Writing code to wire a user interface to a data source doesn’t have to feel like the dark ages! In this blog post, I’m going to detail an alternative to manually connecting a UI to its data source. Data binding is a technique to automatically synchronize a user interface with its data source and can vastly simplify how your app displays and interacts with data.

Data Binding 101

Data binding connects two objects, called the source and the target. The source object provides the data. The target object, which must be a bindable property, will consume (and often display) data from the source object. For example, a Label (target object) will commonly bind its Text property to a public string property in a source object. The following diagram illustrates the binding relationship:

Displaying the relationship between the source and target objects in data binding.

The main benefit of data binding is that you no longer have to worry about synchronizing data between your views and data source. Changes in the source object are automatically pushed to the target object behind-the-scenes by the binding framework, and changes in the target object can be optionally pushed back to the source object.

Establishing data binding is a two step process:

  1. The BindingContext property of the target object must be set to the source.
  2. A binding must be established between the target and the source. In XAML, this is achieved by using the Binding markup extension.

The following code, taken from the accompanying sample, shows an example of performing data binding in XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DataBinding101.HomePage">
	<StackLayout Padding="0,20,0,0">
		<Label Text="Data Binding 101 Demo" FontAttributes="Bold" HorizontalOptions="Center" />
		<Label Text="Forename:" />
		<Entry Text="{Binding Forename, Mode=TwoWay}" />
		<Label Text="Surname:" />
		<Entry Text="{Binding Surname, Mode=TwoWay}" />
		<StackLayout Padding="0,20,0,0" Orientation="Horizontal">
			<Label Text="Your forename is:" />
			<Label Text="{Binding Forename}" />
		</StackLayout>
		<StackLayout Orientation="Horizontal">
			<Label Text="Your surname is:" />
			<Label Text="{Binding Surname}" />
		</StackLayout>
	</StackLayout>
</ContentPage>

Although the BindingContext property of the HomePage class (the target object) can be set in XAML, here it’s set in code-behind to DetailsViewModel (the source object):

public partial class HomePage : ContentPage
{
	public HomePage ()
	{
		InitializeComponent ();
		BindingContext = new DetailsViewModel ();
	}
}

While the BindingContext property of each target object can be individually set, this isn’t necessary. BindingContext is a special property that’s inherited by all its children. Therefore, when the BindingContext on the ContentPage is set to DetailsViewModel, all of the children of the ContentPage have the same BindingContext, and can bind to public properties of DetailsViewModel. For information about setting the BindingContext in XAML, see From Data Bindings to MVVM.

The Binding markup extension can specify several properties, including Path and Mode. The Path property is used to specify the property name of the source object to use for the binding. However, this property name can be omitted provided that it’s the first item in the Binding markup extension.

The Mode property is used to specify the direction in which property value changes will propagate:

  • A OneWay binding propagates changes from the source to the target.
  • A TwoWay binding propagates changes in both directions, ensuring that the source and target objects are always synchronized.
  • A OneWayToSource binding propagates changes from the target to the source, and is mainly used for read-only bindable properties.

In Xamarin.Forms, the Mode property defaults to OneWay, and can be omitted unless a different BindingMode is required.

Property Change Notification

By default, the target object only receives the value of the source object when the binding is created. To keep the UI synchronized with the data source, we need a way to notify the target object when the source object has changed. This mechanism is provided by the INotifyPropertyChanged interface. Implementing this interface will provide notifications to any data-bound controls when the underlying property value changes. The following code example shows the source DetailsViewModel class, which is data bound from XAML, and how it implements the INotifyPropertyChanged interface:

public class DetailsViewModel : INotifyPropertyChanged
{
	string forename, surname;

	public string Forename { 
		get {
			return forename;
		}
		set {
			if (forename != value) {
				forename = value;
				OnPropertyChanged ("Forename");
			}
		}
	}

	public string Surname { 
		get {
			return surname;
		}
		set {
			if (surname != value) {
				surname = value;
				OnPropertyChanged ("Surname");
			}		
		}
	}

	public event PropertyChangedEventHandler PropertyChanged;

	protected virtual void OnPropertyChanged (string propertyName)
	{
		var changed = PropertyChanged;
		if (changed != null) {
			PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
		}
	}
}

The class fires a PropertyChanged event whenever the Forename or Surname properties change. Therefore, in the sample application, as the user enters their name, it’s simultaneously displayed by the two Label instances, as shown in the following screenshots:

data-binding-101-screenshots

Note that as a best practice to avoid unnecessary events being fired, the PropertyChanged event isn’t raised if the property value does not change.

Wrapping Up

Data binding is used to synchronize a UI with its data source, and simplifies how a Xamarin.Forms application displays and interacts with its data. Provided that the source object implements the INotifyPropertyChanged interface, changes in the source object are automatically pushed to the target object by the binding framework, and changes in the target object can be optionally pushed to the source object.

For more information about data binding, see Data Binding Basics. For more information about the INotifyPropertyChanged interface, see From Data Bindings to MVVM. Xamarin University also provides a class on data binding in Xamarin.Forms. Ready to take your data binding skills to the next level? Check out the next post in our data binding series, where you will learn advanced techniques like control-to-control bindings and converters.