Download the tutorial in PDF formatBy Jesse Liberty
Download the code
Data Binding
Data binding is a connection between the User
Interface and a business object or other data provider. The User
Interface object is called the target, the provider of the data is called the source.
Data-binding assists with the separation of the
User Interface level of your application from the other layers of your
application (business objects, data, and so forth). This separation of
responsibility is further reinforced by decoupling the UI target from
its source through the the use of a Binding object.
The binding object can be thought of as a black
box with a universal connectors on one side for the target and on the
other side for the source. There are switches on top, the most
important of which is the Data Binding Mode switch which determines
which way the data will flow.

Data Binding Modes
The Mode (which is of type BindingMode) is an enumeration with three possible values as shown here,

OneTime binding sets the target and then the binding is completed. This is great for displaying data that rarely or never changes
OneWay binding sets
the target and keeps it up to date as the source changes. This is great
for displaying data that the user is not permitted to change.
TwoWay binding sets
the target and keeps the target up to date as the source changes and
keeps the source up to date as the user changes the target or changes
something else in the application that will cause your application to
change the source.
If you were building an on line bookstore and
were displaying information about a book, you might use OneTime binding
for the Title and Author (once you get them, they are not going to
change) and OneWay binding for the price (someone might mark down the
price during the day) but you’d want TwoWay binding for the Quantity on
hand.
The target of your binding can be any public
property of virtually any CLR object (for the minor restrictions on
this, see the Afterward).
You can see this by building a small example;
but even in this stripped down exercise, we’ll keep to a basic 3-tier
approach being sure to keep a relatively strict separation among
- User Interface Layer
- Business Layer
- Persistence Layer
The User Interface
layer will consist of controls that we will obtain from the toolbox and
use as offered for now, though a future tutorial will demonstrate how
to change their appearance using styles and templates.
The Business Layer will be represented by a Book class
We will ignore the persistence layer for now, though this will be covered in great detail in future tutorials.
The Business object and INotifyPropertyChanged
Create a new Silverlight Application, which will create a Page.xaml and a Page.xaml.cs.
Add to the application a Book.cs file which will represent the business layer.
What separates a Silverlight Business object
from one created for (e.g., ASP.NET) is that we want to have our
business object participate in oneway or twoway binding with the UI
layer. To do so, it must implement the INotifyPropertyChanged interface.
This interface requires only one thing: that the
class have an event of type PropertyChangedEventHandler (named
PropertyChanged by convention), Implicit in supporting binding,
however, is that your business object must, by convention, fire the the
PropertyChanged event when any property that is tied to a UI control is
set.
Let’s begin with a simplified version of the Book class,

The first thing to notice is the using statement
for System.ComponentModel on line 1, necessary for the interface
INotifyPropertyChanged. The promise to implement the interface is on
line 5 and the fulfillment of that promise is on line 10.
The property we are exposing is Title, on line
12, and the implementation to keep the target in sync begins on line
15. When a new value is to be set, first the local backing variable is
set as normal, then if the event is not null, the method the event’s
delegate encapsulates is called with a new instance of a
PropertyChangedEventArgs created whose only argument is the name of the
property.
A better implementation of Book.cs
Best practices would be to split out the
creation of the PropertyChangedEventArgs call so that you can use it
for more than one property in the Book class.

It’s easy to see that by factoring out the call
to PropertyChanged, we can now pass in the name of any property and
reuse this boilerplate to invoke the delegate. We’ll demonstrate this
by adding a second property, the author’s name,
With this much of our book class in place and with two properties we can call, our Business class is good to go.
The UI will display this information in a pair
of TextBlocks within the provided grid. Since there are thousands of
books in the on line store, the TextBlocks can know that they are going
to bind to the Title and Author properties respectively, but they can’t
know at design time which book will be the source. That will have to be
determined at run time and set in code.
Therefore, we’ll assign to the Text property of
the TextBlock a Binding object and we’ll tell that Binding object the
Property it will use (but not the source). We can explicitly set the
Mode (a good practice) or let it default to OneWay.

At run time we need to tell each Binding object what its data source is, by setting each TextBox’s DataContext.
DataContext
When you DataBind you tell the target some of
what it needs to know at design time (e.g., you might tell a TextBlock
that it will be displaying the Title of a book) but you don’t want to
tell it exactly which book’s title it will
be displaying. The DataContext is the specific book, chosen at run
time, and assigned to the DataContext property of the Framework Element
(in this case the TextBlock) so that it knows “Oh, I get the Title from
this book” More on this shortly.
The DataContext can be raw data, but far more
common is to assign an object of type Binding. A Binding object knows
how to get the data needed by the target from the source. It is our
universal connector with the Mode switch on top.
Another advantage of using a DataContext is that
it allows elements to inherit information about the data source from
the parent element where it makes sense to do so.
Presumably some action by the user would select
a book, and the Book business object would be assigned as the
DataSource for the TextBlock.

To keep the example simple, we will just create
a book (line 18) and assign a title to it (line 19) and then assign
that book as the DataContext of the Title on line 20.
Pop Quiz: Whose Data Context just got set?
There are three reasonable answers, and it turns
out to be the least immediately intuitive for many folks, and yet this
is a very common naming convention.
1. The property Title that we set on line 19
2. The attribute referred to by Text=”{Binding Title}” on line 11 in the lower pane
3. The Textblock x: Title, also on line 11.
Perhaps somewhat surprisingly the answer is #3, which you can easily prove, by changing the names to AA and TT,

I point out this potential area of confusion because almost all the documentation, books and code you’ll read will
use the same name for the control, and for the property, and as long as
you are clear about how it works it need not be confusing, though an
argument could be made for a differentiating convention (e.g, Title and
TitleControl) but such thoughts set off long rancorous discussions on
newsgroups that can be great fun when you can’t sleep.
The Logic of Data Binding Step By Step
1. Create a target object (e.g, TextBlock) that and identify its Dependency Property that will be passed to Binder (e.g., Text).
2. Identify
the Property name from a source that implements INotifyPropertyChanged
(e.g.,Book) and a property that calls the PropertyChanged Event when
its value is set (e.g., Title).
3. Map the Target to the Source’s property using a DataContext in the code-behind.
It’s easier than it sounds, especially the second time.
The XAML file has all the UI that we can know at
design time but no more.. In this sample, we’ll use two TextBlocks to
stand in for the complete UI of a real program.
The TextBlock is ideal to read-only fields (such
as Title and Author). We want our Silverlight application to be able to
display the details of any book that might be chosen, so we don’t want to hardcode the title and author,

That will work, as long as you only have one
book. Instead, we want the Text to be determined at run time. To make
this work with whatever book is chosen, we’ll tell the Text field to
use a Binder.

The Binder defaults to OneWay as its Mode
(though we can (and should?) set this explicitly). We tell the Binder
which property it maps to (Title, Author), though we do not tell it which object it connects to as we cannot – we won’t know until run-time.
The object it will connect to at run-time is the data context, and of course the data context must have the appropriate properties.
So, for example, the Title text block knows that
it is bound to a Title value, but it has no idea whose Title property.
And that is just as it should be.
For
convenience, in this example we create the book which will be the
DataContext in the OnLoaded event handler and we gin up a book out of
thin air, but all of that is just a stand in for what would really
happen; which is that the user would somehow indicate which book is
wanted, and an event handler would be called which would be responsible
for creating or populating the book and then making it the data source.

The key to the Binding, however, is to make the business object (the Book) the DataContext for the two TextBlocks.

That completes the binding; now we have targest
(the TextBlocks) each with a Binding. Each binding has a DataContext
(the book) which has the appropriate Property (Title and Author
respectively). thus we can display the information:

Testing INotifyChangedProperty
If the Book information were to change, the fact
that Book implements INotifyChangedProperty would cause the UI to
update. You can test this quickly as follows.
1. Add a third row to the Grid and Add a Button whose name is Change and whose Content is Change Book as shown,

2. In
code-behind, make the Book a member variable, (so it can be accessed
from any method). and move its instantiation to the constructor Wire
up and implement the Change button’s click method to change the title
and author of the book.
3. Note that when the book’s properties change, the UI is updated automatically through responding to the event.

Data Contexts are Inherited
Rather than setting the DataContext individually
for the Title and the Author, we notice that both are child elements
of the same grid. That allows us to assign the book as the Data context
of the grid and both the Title and Author will “inherit” thie Grid’s
data context unless either or both set their own.
Two Way Binding
Two way binding allows you to ensure that the
updates work in both directions. That is, when the source is updated,
the target is updated, but when the target is updated, the source is
updated. This is critical for interactive applications.
This of course is much more difficult.. So sit down. Here’s what you have to do.
First, You’ll need to change one of your
TextBlocks to a TextBox which is a much better UI element for text
entry. In this example we’ll make the Author a TextBox. Second we’ll
need to change the Mode to TwoWay. Okay, the hard part is over.
When you start the application it will fill the
text box with the name currently recorded in the book object as the
value in the Author property. If you change what is in the text box,
and leave the text box, the new data will be inserted into the Bok
object. Honest.
Since I know you won’t believe me, (actually, I could
be lying; how would you know? I could say it changed the book, but how
could you really be sure? So let’s make sure.) add another TextBlock
named AuthorOut to the UI. We’ll have it show what is in the author
field. That way if the book is updated, this should reflect the change.
While we’re at it, let’s give the grid a second column so that it looks
a bit tidier.

With that in place, we can put the Author
TextBox (for input) next to the Author TextBlock (showing the state of
the object). That is all we need to verify that after you change the
Author’s name, it is in fact updated in the Book object,

Notice that both of these UI elements bind to
the Author property, the first binding in TwoWay mode to allow changes
made in the UI to update the Book, the second binding OneWay for
display.
Start the application. Now click in the text box
and change the authors name and then leave the text box. The output
reflects that the book was changed (and by being changed, notified the
UI to update itself with the new information).

Expanding the Book Class
Let’s expand the Book class to add a few more
properties that might be reflected in other UI controls, including a
data bound UI control. Here is what an instance of a book might look
like,

The significant properties of this book are
reflected in the properties of the Book Business object, along with at
least one Business property not immediately obvious from the tangible
item itself (quantity on hand)

Displaying the New Properties
To get going, let’s create a prompt using a
DataTextBlock for each of the new properties, and add display controls
as shown in the following table
|
Book Property
|
Control
|
Notes
|
|
quantityOnHand
|
TextBox
|
Two Way
|
|
multipleAuthor
|
CheckBox
|
Two Way
|
|
Chapters
|
ListBox
|
One Way, Data Bound
|
The steps to displaying these properties are to
add three new rows in the data grid and then to add a TextBlock for
each prompt (bound to the Book) and the appropriate control for each of
the new types.
We start by modifying the Grid, to allow extra rows

Next we add the paired controls: one for each prompt, and one for each property,

Not much is new here but there are a few minor but important things to notice:
- A convention is created that the label and the value are given
paired names, such as TitlePrompt and Title, AuthorPrompt and Author.
This makes predicting control names easier, and thus maintenance easier.
- The Value TextBlock gets its value from a Binding object whose name
is the same as the name of the control (thus the Property that feeds
Author is the Author property).
- Mode is explicitly set rather than relying on the default value of OneWay
Also note that I’ve decided to explicitly align
all controls vertically along the bottom, all prompts on the right edge
of the column, and all values along the left of the column.
We’re now ready to use new controls for the new
properties. Let’s skip over the chapters for a moment and go on to the
MultipleAuthors prompt. This is our first two-way prompt: a checkbox.

The CheckBox is bound to the Boolean value
MultipleAuthor, and a two way connection is established just by setting
the Mode. As noted earlier, that’s all you have to do. If the user
changes it to checked, the underlying data object (the book) will have
its data changed (the MultipleAuthor property will change from false to
true).
To see this, we’ll add a new button, Change that will toggle between displaying two different book objects

As you can see, there’s nothing special about
the button; the magic is in the code. We accomplish this small miracle
in small steps. First, pull the reference to the Book out into a member
variable, second create three new member variables

You’ll initialize the two books in memory and
have the first referred to by b1 and the second referred to by b2, and
currentBook will toggle between them. A hack, I admit, but it will work
and will keep the code simple.
The premise here is to mimic the idea that in a “real” system you’ll be picking one book not from two, but from many,

As you initialize each book, you’ll populate the book’s properties, including whether or not there are multiple authors,

In this version of the program, we’ll pay
attention to the Boolean, but we won’t parse the string of author
names. In a more sophisticated version we might use a collection of
author names, or other more extensible solution.
TextBox
In addition to adding a CheckBox we add a second
Read/Write field, the TextBox, which will display and allow the user to
update the number of copies of the book on hand.

In our design, each book knows how many copies of itself are in the store; there certainly are other ways of designing this.
ListBox and Binding to a List
Finally, we come to the Chapters. The Book object defines the Chapters as a list of strings

You initialize the names of the chapters when
you initialize the book (though, again, presumably this would be
obtained from a database or web service),

When the book is displayed, the chapters will be
displayed in the list box. When a new book is chosen, that new book’s
chapters will be displayed. You could
iterate through the new book’s chapters and create a new set of
ListItems, but again that is error prone and doesn’t scale well. Once
again, Data-binding is a more satisfactory solution.
Since the DataSource for the Title and Author
(the current book) will also have the correct list of Chapters, you can
assign the Chapter property of the Book to the ItemSource property of
the List Box, and as the DataSource is changed, the chapters will be
changed appropriately,

The next two images show the new details of the two books displayed as the user switches among them.


Afterword
It isn’t quite true that you can bind to any CLR
Object; there are actually two restrictions, though they are almost
never a problem. The first is that the target must be a
FrameeworkElement. FrameworkElement inherits directly from UIElement
and is an ancestor to all the visible UI elements you’ll want to bind
to, as shown here,

FrameworkElement has the DataContext property you’ve seen in use above.
The second restriction is that the property you assign as the target must be a Dependency Property.
Dependency Properties
Don’t panic; just about all the properties you want to bind to are dependency properties, and dependency properties are great. In fact, they are used all over Silverlight.
Silverlight 2, (like WPF) extends object properties using the Silverlight 2 property system.
Any property that is extended in this way is called a Dependency Property.
Dependency Properties are an incredibly powerful part of Silverlight. The
essence of Dependency properties is that their value is determined at
run time based on a confluence of factors, each evaluated in a specific
order. These factors include:
- Themes
- User preferences
- Data binding
- Storyboards and animation
- Templates and styles
- Parent/child relationships
- The results of callbacks
Dependency properties deserve and will receive their own complete tutorial, but a very brief overview will help with understanding data-binding.
Pay No Attention To The Type Behind The Property
The key to dependency properties is that each Dependency Property is backed by a type
rather than the standard approach of backing a property with a private
member variable. Somewhat confusingly, the name of the type is
DependencyProperty.
The other major player in the Silverlight
property system is the DependencyObject: the base class that enables
the Silverlight property services on its many derived objects:

An instance of a Dependency Property is called a
Dependency Property Identifier, and is typically exposed as a static
readonly member of the type that holds the dependency property. This
is usually the point where your eyes glaze over and you go off shaking
your head and looking for an ice cream. I find a table of terms can
help:
|
Term
|
Definition
|
|
Dependency property
|
A property that is backed by a DependencyProperty
|
|
Dependency property identifier
|
An instance of a DependencyProperty
|
|
CLR Wrapper
|
The get and set for the property. See the example IsSpinning just below.
|
|
DependencyObject
|
Base class of all the objects that participate in the Silverlight dependency property system.
|
The following example of the IsSpinningProperty is from the Silverlight help files

In the small example shown above
IsSpinningProperty is a DependencyProperty. It also provides a CLR
Wrapper IsSpinning. The getter gets and casts the IsSpnningProperty and
the setter calls SetValue on IsSpinningProperty passing in the value to
set.
Setting Dependency Values in XAML
Because XAML uses Type Converters, you can
typically simply assign a string value to a XAML attribute for
Dependency values, as you are probably used to doing for the Background
value for the Canvas

Setting values for Dependency Properties is greatly simplified by the get and set implementations exposed by the CLR wrappers,

In the code above, LGM is the canvas defined in
XAMAL in the previous image. The value in LGM cut to 80% of its
original value through the set implementation of the CLR wrapper;
though that is invisible to the programmer.
Using the Documentation to Find Dependency Properties
You can tell that the Canvas’s Background
property is a Dependency property by looking at the Canvas’s base
class: Panel. Examining Panel’s Members (shown abridged here), reveals
the key, Background is matched by BackgroundProperty.

You can identify Dependency Properties by the fact that the class they are a member of will have a field of the same name but appended with Property (and that is of type DependencyProperty.
Clicking on BackgroundProperty will bring you to its definition showing that it is in fact of type DependencyProperty.
To spot check, you might open up TextBox. You
know that you’re likely to want to data-bind to the Text property. A
quick look at the property list finds no TextProperty property. An easy
mistake. You need to check the Fields, and sure enough, there it is,
