10 reasons to consider WPF for your next desktop application - Reason 2. Databinding

Here is part 2 of Josh Twist's 10 part series on the reasons to consider WPF for your next desktop application, this part explores the topic of databinding.

Earlier I introduced a series of posts entitled 10 reasons to consider WPF for your next desktop application. If you haven't read the intro yet, better head on back and read it first.

At this year's ADC TechBriefing I gave a talk entitled "Real World Applications with WPF" and in it I introduced some of my 'laws of WPF', including the zeroth law:

"If you're not using databinding, you're probably doing something wrong"

For the nitpickers out there, there is of course an exception to every rule, but hopefully this stresses how important and how great I think databinding in WPF is.

Why?

Window Forms 2.0 really raised the databinding bar but the fact remains that databinding was a bolt-on to WinForms. An afterthought, if you will. Not so with WPF, binding was built in from the start and it shows. It has been beautifully implemented and I think I have a kind of unhealthy addiction to it.

I love the way you can bind pretty much anything to anything. For example,

  • Controls* to objects (or POCOs)
  • Controls to controls
  • Controls to XML

You get the idea. Here are some quick examples.

In this first example I've created a collection of Book objects (an ObservableCollection<Book> to be exact). The book object looks like this:

Class Diagram of the Book class

I told you it was simple. The important thing to note is that it has three properties (Name, Author and CustomerRating) and implements INotifyPropertyChanged. I won't bore you with how to do that now but it's very simple (more here: How to: Implement the INotifyPropertyChanged Interface).

Once we've created this collection (which we fudge manually in the Window's constructor) we simply set it to the DataContext of the window and start binding away.

Example 1 - simple form

You can run this application in xbap form from here: Reason 2 XBAP.

First, we bind the ItemsSource of the ListBox on the left to the DataContext of the window

<ListBox Name="_lstBooks" ItemsSource="{Binding}" />

Then we bind the GroupBox's (the fieldset surrounding the textboxes) DataContext to the selected item of the listbox. Nice.

<GroupBox Header="Book Details" DataContext="{Binding ElementName=_lstBooks, Path=SelectedItem}">

Then we bind each TextBox to the relevant property. Very nice.

<TextBox Text="{Binding Name}" />
<TextBox Text="{Binding Author}" />
<TextBox Text="{Binding CustomerRating}" />

Note that, because our binding is two-way (the default) if you change the values in the textboxes these will be persisted in memory on the actual instance. So if you change to look at another book and come back, your change will still be there. All ready for you to save to the database when the user clicks save (if I'd have had the foresight to create a Save button, or even a database for that matter).

That's probably "binding to data 101" covered, albeit at breakneck pace. But what else can we do? You can do much more than just binding to boring data! How about binding a transform to a control?

You may have noticed in the example above that there's a zoom bar at the bottom left of the screen (you can see this better in the xbap). This slider will actually zoom in the form.

Example 1 - simple form zoomed in

All achieved declaratively in Xaml using databinding like so:

<Slider Name="_sliderZoom" Minimum="0.8" Maximum="5" Value="2" />

<!-- snipped for brevity -->

<Grid.LayoutTransform>
<ScaleTransform
ScaleX="{Binding ElementName=_sliderZoom, Path=Value}"
ScaleY="{Binding ElementName=_sliderZoom, Path=Value}" />
</Grid.LayoutTransform>

And there's more...

We're still only seeing the tip of the iceberg as to what is possible with binding - there's so much to it. Lets take a quick look at another feature ValueConverters and MultiValueConverters. Look at Example 2 (you can get to this by clicking the "Go to Example 2" hyperlink in the bottom right hand corner of the Reason 2 XBAP).

Example 2 - color selector

The idea is pretty simple. Three sliders, one for each of Red, Green and Blue, and the background color of the Page is bound to these controls.

But how can I bind one thing (the Page's background color) to THREE controls? Easy, with a MultiValueConverter and MultiBinding.

<Page.Background>
<MultiBinding Converter="{StaticResource colorConv}">
<Binding ElementName="_sliderRed" Path="Value"/>
<Binding ElementName="_sliderGreen" Path="Value"/>
<Binding ElementName="_sliderBlue" Path="Value"/>
</MultiBinding>
</Page.Background>

Be sure to check out the full source to see how this is done in full (available at the end of the series).

* I should use the term "elements" instead of "controls" when talking about WPF but it helps the transition.

Originally Posted by Josh Twist on 12 Oct 2007 here.