Thursday 19 April 2012

Binding in Windows Presentation Foundation (WPF)

What is this post all about?

Any programmer, novice or professional, who has wanted to pick up WPF and thought "hey, I know a few programming languages already. How hard could learning a new one be?" has found themselves rapidly and painfully disillusioned.

There is nothing inherently difficult about the concept of WPF. There are essentially 2 components; XAML and your preferred .NET language out of C# or VB.NET. XAML is a glorified version of XML, but tuned towards application programming. It is used to control the aspects of the application related to display and behaviour, whereas the traditional programming language is for aspects related to data and business logic.

Why is XAML difficult?

WPF is firmly grounded in the concept of MVC (Model-View-Controller) or MVVM (Model-View-ViewModel), depending on which book you read. The idea is that the view does not 'own' any data. Your model owns data, and it is your controller's / view model's job to handle user interaction and to marshal data in and out in a way that suits the application's usage. "If the view cannot own any data," I hear you ask, "how does it display anything to the user?" Good question. Through data binding.

Tell me more about binding...

Ok, since you asked so nicely. Binding is the act of linking a property's value to another property. Depending on how it is set up, a change in one property causes an event to fire which causes the other property to automatically update. If you have a binding between the text in some text box and a string property in your model, when the user navigates away from the text box after typing something, a property changed event gets fired, causing an update of the value in the model.

How does binding work? Literally the only way to answer is by magic. There are so many ways to bind data that it really comes down to horses for courses. You could define a resource in your window that points to the data model and bind the property to that. You could set the DataContext of some control and bind to that. There are more ways than I care to go into now.

The most confusing thing is when you bind a control that displays a collection of items to a collection in a data model. The control somehow just knows that it has to display each item next to each other, or on top of each other, etc. depending on the type of control. For example, you could bind a dropdown box to a List<String> property and it will allow you to select one of the items from that collection. It gets even more confusing when you bind a property of some other control to a property in that collection control. When you select a different item, the bound property also changes.

You're confusing me :(

No doubt. I'm confusing myself if I'm perfectly honest. That is why I spent days writing an application so that I could illustrate what I am talking about with an example. It is a very rudimentary contacts list type application. You can scroll through a list of contacts, click on one, and it will show you more details about the contact in question. You can download the compiled application here;

http://dl.dropbox.com/u/21044234/ContactsLayout.exe

And if you are feeling brave, you can get the source code here;

http://dl.dropbox.com/u/21044234/ContactsLayout.zip

It is built in Visual Studio 2010 Express. You will notice from the source code that, apart from the model data setup, it contains absolutely no source code. The entire application, from the user interaction through to the data presentation, is written in XAML and bound to the data model. It illustrates many of the powerful ways that WPF can be used to write pretty and interactive applications, which is what I like about it.

1 comment:

  1. The biggest struggle I have with XAML is the million subtly different and mutually incompatible ways to do very similar things.

    Oh, and that text binding styles/other formatting to the data results is made rather difficult. I spent quite a while getting things to work, only to discover that I needed to do it a completely different way if I wanted it to update with the data. Joy. There are probably about a hundred commits in that project's source history where I'm committing stuff that works, before I break it and forget exactly what incantation I used.

    Other than the general schizophrenia of it all, it's great :-)

    ReplyDelete