Design: Binding Oriented Programming
Recently I’ve been thinking about the way I’ve started to code applications, especially user interfaces, and I realised that I use a hell of a lot of data binding (”Really? You don’t say! Go on…”). In fact, a lot of the way I design components and applications is based on the assumption that data binding will be there, and if data binding weren’t available I’d probably take very different approaches.
Yesterday a friend asked me what I’d do if I had to use a UI framework that didn’t have good data binding support. I thought about this for a while, and I came to the conclusion that the time savings and productivity increases that I personally get from using data binding would outweigh the time it would probably take to build a (relatively simple) data binding framework of my own.
Here’s my philosophy:
In most projects, 80% of the code found in the code-behind of a typical page, window or user control (ASP.NET, Windows Forms or Windows Presentation Foundation) could be replaced with data binding. There is no excuse whatsoever for a code-behind file comprising of more than 200 lines of code.
When I open the code-behind for a piece of UI and I see it has more than, say, 200 lines of code, or a ton of event handlers for every little interaction that might take place, and lots of references to controls from the code-behind, I see the code as being “brute forced”.
Brute force programming goes something like this:
- The developer needed to solve a problem with code
- He wrote the code
- It didn’t quite do everything he needed
- He wrote some more code
- A special circumstance came up where if XYZ is HKLM, then ABC should behave differently
- He added some more code
- Repeat forever
The idea is you throw as much code at a problem as you can, until eventually you kill it.
When you begin to think about how components interact in terms of how they are bound, that is, when you practice Binding Oriented Programming (BOP), your code becomes much, much smaller, is much less coupled, and can handle many more circumstances than you might originally plan for. Allow me to explain why.
Synchronization
Without binding:
With binding:
The key reason why data binding provides all of these benefits is the automatic synchronization between the source and the targets. This synchronization might happen in both directions, or it might happen only in one direction, but the point is it’s there. When we don’t use data binding, it’s up to us to keep data in sync, and the more things that can possibly effect that data the more code we have to write to glue them together.
When you stop thinking in terms of what data is set on a component, and instead think in terms of what data is synchronized between components, you begin to think in a binding oriented way.
If a Slider is a representation of the zoom level of a document, then the Slider and the zoom level are synchronized. By setting the Slider’s value in code by yourself, you have to work very hard to keep the two in sync. If something else affects that zoom level, such as a Zoom menu later, you have to write the code to go and set that value. You’re handling that synchronization yourself.
Pull, don’t push
When you look at a system that doesn’t use binding, the primary interaction between the code-behind and the markup/designer code is that of a push model - the code-behind pushes data into the controls. The code-behind knows what every control needs, and it has the job of setting it.
You can spot this push model very easily - the methods and properties in the code-behind will have references to the names of controls in the UI, for example:
nameLabel.Text = someData.Name;
Even when you use data binding, or you think you’re using data binding, you can run into this trap:
dropDown.DataSource = myListOfCustomers;
The fact that there exists a reference to a UI control from the code-behind suggests the existence a push model. It implies that the code-behind has authority over the controls. Since the markup is already dependent upon the code-behind (as it inherits from it, and because it uses things such as event handlers on the code-behind), when you start referencing UI components from code-behind you make that dependency two-way, and the two become very tightly coupled.
When you practice Binding Oriented Programming, you develop your code-behind using a “pull” model. Your code behind becomes a provider of data, rather than the pusher of data. Your UI controls become pullers of data, and the dependency exists only one way - your UI components depend on the code-behind, but the code behind doesn’t depend on the UI.
Let me give you an example of changing something from being a pull model to a push model. While my example will use Windows Presentation Foundation, the approach can work just as well in Windows Forms and ASP.NET:
Let’s say I have an Address class that represents the postal address of a person, and on a Window I want to display the various bits of the selected Address as a single string.
The markup for the Window might be:
<Window
x:Class="Example.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
>
<StackPanel>
<TextBlock
x:Name="_addressLine1TextBlock"
/>
<TextBlock
x:Name="_addressLine2TextBlock"
/>
<TextBlock
x:Name="_addressSuburbTextBlock"
/>
<TextBlock
x:Name="_addressPostcodeTextBlock"
/>
</StackPanel>
</Window>
And the code-behind could be:
class Window1 {
private Address _selectedAddress;
public Window1() {
InitializeComponent();
}
public Address SelectedAddress {
get { return _selectedAddress; }
set {
_selectedAddress = value;
_addressLine1TextBlock.Text = _SelectedAddress.Line1;
_addressLine2TextBlock.Text = _SelectedAddress.Line1;
_addressSuburbTextBlock.Text = _SelectedAddress.Suburb;
_addressPostcodeTextBlock.Text = _SelectedAddress.Postcode;
}
}
}
You can see the Push model: The code-behind has a reference to the TextBlock, and so the code-behind is dependent upon that TextBlock. If something else on the Window were to display the same address, or if the address changed, we’d have to add more code to keep the data in sync.
Let’s change it to a Pull model. The code-behind for our Window can become:
class Window1 {
public Window1() {
InitializeComponent();
}
public DependencyProperty SelectedAddressProperty =
DependencyProperty.Register("SelectedAddress", typeof(Address),
typeof(Window1), new UIPropertyMetadata());
public Address SelectedAddress {
get { return (Address)GetValue(SelectedAddressProperty); }
set { SetValue(SelectedAddressProperty, value); }
}
}
Note that while I’ve used a DependencyProperty in WPF, you could easily implement INotifyPropertyChanged on your form in Windows Forms to achieve the same functionality. Now the markup simply becomes:
<Window
x:Class="Example.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
x:Name="_this"
>
<StackPanel>
<TextBlock
Text="{Binding ElementName=_this, Path=SelectedAddress.Line1}"
/>
<TextBlock
Text="{Binding ElementName=_this, Path=SelectedAddress.Line2}"
/>
<TextBlock
Text="{Binding ElementName=_this, Path=SelectedAddress.Suburb}"
/>
<TextBlock
Text="{Binding ElementName=_this, Path=SelectedAddress.Postcode}"
/>
</StackPanel>
</Window>
While this is a pretty simple example, the concepts can be extended to just about every UI related scenario you can imagine. When you learn to spot the signs of a push model, and you invert it to become a pull model, you’ll find that the code becomes much easier to maintain, much more flexible (as other UI elements can reuse that data), and much more modular.
Incidentally, the practice of having the UI bind to it’s own code-behind, a trick I’ve dubbed “code-behinding“, is the feature that probably has me most excited about Windows Presentation Foundation right now. You can do the same thing in Windows Forms and ASP.NET, but the designer/markup support really isn’t there for it. In XAML, you can achieve it all using markup.
These are just two of the core traits of Binding Oriented Programming: the implicit synchronization between data and components, and the inversion of your code-behind from a traditional Push model to a much more sophisticated Pull model. I think there are more of these traits, but I’m still trying to organise my mind around them - this blog entry is just a “thought-in-progress”.
I’ll end this entry with a challenge: open up a project you’ve worked on over the last few months, and try to find a page or form with more than, say, 300 lines of code-behind. Try to identify how much of that code is simply spent keeping data in sync between UI elements and objects, and how much of it, and how much of it involves the code-behind having authority over the UI controls. Think about the ways you could make that synchronization more implicit using binding, and how you could invert at least some of that Push model into a Pull model. I’d love to know the challenges that people face when attempting to make this shift.
Filed under: Binding


I have searched for an easier way to do databind like things in ASP.NET. I’d like to see how your ideas can be implemented on that platform.
My problem with declarative databinding has been maintainability. Granted, it’s easy to get the databinding correct the first time, but then there are at least two problems:
1. Names can change. Or the abstractions. Newer tools will perhaps detect mismatches at compile time, but that wasn’t the case in ASP.NET 1.1
2. How do I reuse declarative databinding? If I write the same binding code all over the place, which is kind of what VS 2005 invites us to do, and there are no refactoring tool support, then any change can morph into a maintenance nightmare.
BTW, a codebehind and its ui is tightly coupled. As you say, one inherit the other, a tighter coupling than that is hard to get. That doesn’t mean I disagree that a push model is bad. I do. I just think you use the wrong arguments.
Great article. I just try it with Windows Forms and it works. It’s pretty easy: Just add a new Data Source to your project selecting the form and drag the property from the Data Sources window.
So I have one property working.
How about data sources that return multiple objects?
How about a Master / Detail relationship?
Looking forward to rewrite most of my code. Je je.
Thanks.
Hi Thomas,
I agree with your observation that you can’t get more tightly coupled than inheritance. I guess what I meant to say was that the nature of communication between a base class and its decendants can be complex, and when you make that communication flow two ways explicitly you introduce even more complexity and less flexibility.
Rt. Greg,
Glad you got it to work. I’ll try to put together a few examples of how to invert the code-behind of different frameworks into a pull-model.
[…] Stovell on Binding Orientated Programming 18 03 2007 Paul might be onto something here. I’ve seen first hand how productive Paul can be with WPF and I wonder how much of it is due […]
Paul,
I would love to see a couple of examples on how this can be implemented in ASP.NET.
Thanks
Paul,
I’m very glad to read this article. But if the data in datasource need to be processed before it is shown in UI elements. The normal case is that the nil should be displayed as zero.
Thanks
Paul - Interesting points - and has helped gel some of my own thinking. Thanks.
One thing I’m not 100% clear on (and I might be missing something here) is how could you achieve the same Pull-model using INotifyPropertyChanged (ie. in the non-WPF scenario)?
Cheers.
@Xaxie, I found this kind of data processing to be one of the strongest arguments for using data bindings and custom business objects. E. g. if I have a DateTime property that display just the time if it is today’s date, the date if it is a recent day or an empty string if it is DateTime.Min, I just implement another string property called e.g. MyDateFormatted or DisplayMyDate which handles all this kind of logic in its getters and setters and use this property for data binding.
This way I can even test this logic using unit tests and use the same logic e.g. for a windows forms, asp.net and data export scenario.
[…] fits very nicely into the Binding Oriented Programming idea I discussed a while back. If you use a solution like this, you’re recognizing that every […]
[…] Binding Oriented Programming - interesting post to read, but I wonder how all this fits into the MVP pattern (my guess is not much). […]
[…] I explained in my Binding Oriented Programming post, I give the root element of all of my XAML files an “x:Name” of […]
[…] Binding Oriented Programming (BOP) is something that I’ve been championing to a number of Readify colleagues. In my original post, I gave an example of how the BOP approach could be applied in a Windows Presentation Foundation application. Then in a post about the SecurityManager, I showed an example that used Windows Forms and followed it up with another one using ASP.NET. Tonight I’d like to show another example using Windows Forms. […]
Good article, I seem to spend alot of my time synching controls & data in the misguided belief that they weren’t appropriate for binding. Guess I’ll take a step back and rethink this now. Would love to see some examples for winforms & asp.net Paul.
[…] presentation is adapted from my articles on Binding Oriented Programming. I will not be using any slides, instead I will just be talking and running through code […]
[…] with this engagement me and my fellow Readifarian Ducas Francis decided to give Paul Stovell’s binding oriented programming a go. Paul is a big advocate of Domain Modeling and using binding whenever possible and how that […]
Hi,
Interesting article…
Speaking purely from an ASP.Net point of view I always avoid the “Pull” model you describe. There are a number of reasons for this:
1. The designer support for web forms is very poor.
Visual Studio will NOT throw a compiler error if there are issues with some databound controls. Instead, you will be left with ambiguous run-time errors when you execute the application. This is one major drawback for me in an enterprise application that involves multiple developers at different levels working on the same code.
- Intellisense is poor when working in the aspx. I’m much more productive in the codebehind.
2. Codebehind model is more Object Oriented
3. With the codebehind model I can easily manipulate data, handle exceptions or place in data in state before I bind to any controls. I find this approach works much better than responding to a controls databound events.
4. I disagree that BOP creates more maintainable code. I have had to fix bugs in BOP type code before and have found that it is a nightmare to maintain. For example, if we have a FormView control bound to a SQLDataSource, then all the controls (textboxes,
dropdownlists, etc..) are populated all at once when we bind to the SQLDataSource. Now what happens if we want to create a cascading drop-down. In other words, we only want to populate one dropdownlist (and not the whole form) when the value in one drop down list changes? The answer is that we have to write some horrible hacks as a workaround.
This last point is probably the main reason why I prefer a “Push” approach for web applications and avoid BOP.
Web 2.0 has really brought Javascript and partial rendering into the spot light. The idea is that we only want to update specific data on the screen at a time. I’ve heard one guy make this analogous Lego. The old approach was to bring the whole page down to the client as one block of lego all at once. However, the new approach should be to only bring down the most essential building blocks to the client at the start and construct the rest of the screen with new lego blocks (using AJAX) when we need them. Hope that makes sense!
I guess it boils down to individual preference and I am definitely sticking with the “Push” model for the moment.
Great posts on DataBinding (I really enjoyed the videos).
I would LOVE to see an example with more complex (realistic) DataBinding. For example, most forms need to display a list of existing records, a user then selects a record to edit, but the record needs lookup data (like choosing an existing customer for a Sales order, or a product for a Line Item).
Implementing more realistic forms introduces more challenges that I would like to see how you tackle. For instance, do you have a button with three dots to open another form to choose a customer? Do you let a user enter an an ID directly? Do you use a drop down list or grid?
What about child collections? Let’s say a customer is allowed to have multiple addreses (a child collection). Do you use a grid? Do you have a separate tab with a read ony list and have the user open a separate view for editing/ adding new?
Is there anything you can share regarding these more complex issues?
TIA
[…] day I’ll work out how to get binding oriented programming working and then I’ll make Paul Stovell […]
[…] UI layer. Maintaining state consistency is necessary in all layers. I believe that SyncLINQ - and Binding Oriented Programming in general - can radically reduce the complexity in desktop applications while also providing […]
[…] with this engagement me and my fellow Readifarian Ducas Francis decided to give Paul Stovell’s binding oriented programming a go. Paul is a big advocate of Domain Modeling and using binding whenever possible and how that […]
[…] have a fully running application so please bare with me. I, as usual, will use domain modelling and binding oriented programming all the way so hopefully you find this useful. Please note that this not an architecture post; so […]
Hi Paul, why name the window object _this and reference it in the xaml, when you can set the DataContext for the parent heirarchy (in this case your window) and then just bind to the path of the property?
it looks like you’re just mimicking what the DataContext provides, so, what advantages are there in naming the window object and refering to it by element name?
Cheers,
Rob