Binding Data to WP7 Pages

When you are building apps, have you thought about how much time you spend
populating fields and lists? You would probably be surprised if you were to
keep track of the amount of time you spend performing this seemingly simple task.
Unfortunately, most of the time we are used to this repetitive task that we
perform over and over as many frameworks do not provide a real solution. Since Windows Phone 7
(WP7) applications are created using Silverlight
it actually provides a quite elegant solution. As you are probably aware eXtensible
Application Markup Language
(XAML)
provides a flexible and structured method for building screens. Included within
XAML is a very powerful method of data binding, which drastically reduces the
manual work you need to perform.

The first thing to understand about WP7/XAML data binding is DataContext.
The DataContext essentially provides the root object, which is used to pull
data from. Specifically, this object specified will be used as a place to pull
property values. Thus if you were to specify an object with a PageName property
you would be able to use that property value to set the text value of a
TextBlock for instance. To see how this plays out we can create a simple
PageName property as shown below:

public string PageName
{
get
{
return "Page Title 1";
}
}

Next we need to bind a Text Block as defined in XAML to this property as
shown below:

<TextBlock x_Name="PageTitle" Text="{Binding PageName}" />

As you can see, the simple code {Binding Page Name} within the Text
parameter is all you need to parameter PageName. If you were to go ahead and
execute this you would find out that the TextBlock would show blank. The reason
this would not automatically populate is that we have not specified a DataContext
for the PageTitle TextBlock. We can set the DataContext using the following
code snippet.

PageTitle.DataContext = this;

Provided the PageName property exists on the object referred to by
"this" you can execute this code and see the PageTitle TextBlock shows
the value specified by the PageName property. While this does work it is not
terribly efficient as you do not want to specify the DataContext for each and
every field. In fact, the DataContext also works by pulling it from its parent.
Thus if you were to place the TextBlock inside a StackPanel called you could
use the following state to specify DataContext.

TitlePanel.DataContext = this;

Since the PageTitle TextBlock is located within the TitlePanel it is able to
pull the DataContext from its parent object. This concept becomes even more
important when you want to bind to a list. Ideally, you would want to be able
to specify the source of the list items as the DataContext on the List and have
the List items bind automatically to each item. In fact, that is exactly how it
works when you are binding to lists. The following XAML snippet demonstrates a
simple list that binds the ItemsSource to a property called Items.

<ListBox x_Name="MainListBox" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" />
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

As you can see, this XAML snippet uses a ListBox ItemTemplate that contains
the DataTemplate used to describe the items within the list. The DataTemplate
contains two TextBlocks, which bind to properties LineOne and LineTwo.
Explaining how this works is very simple; the ListBox is bound to an Items property
that returns an ObservableCollection, which contains items that implement the
INotifyPropertyChanged interface as well as the two properties LineOne and
LineTwo. Like the examples above, the ListBox will need to be provided with
DataContext and be able to get access to the Items property. But why an
ObservableCollection instead of a standard List? The ObservableCollection is
one of the better aspects of the XAML data binding. The ObservableCollection
allows XAML to automatically monitor the collection for changes. Thus if you
add/remove items within the collection, the ListBox bound to it will update to
reflect the changes. The ObservableCollection itself will only XAML to monitor
inserts/deletes from the collections. To monitor properties of items within the
ObservableCollection, those items need to implement the interface
INotifyPropertyChanged. This interface allows XAML to catch properties as they
change. Thus if you were to change the LineOne property of one of the items,
the ListBox would be updated to reflect the changes.

Conclusion

As you can see with the above examples, data binding to simple TextBlocks is
quite simple. If you set up your code correctly you should be able to
drastically reduce the manual coding necessary for updating onscreen fields.
The real bonus data binding comes in when you are working with lists where updates
to the underlying data are automatically reflected on the screen. If you start
your project using the Windows Phone Data Bound Application template you can
start your project off on the right foot and see further examples of how to
implement data binding.

More by Author

Must Read