Disclaimer: This blog post is theoretical notes about an interesting subject, and does not contain a working solution. I will probably provide a solution in the future, but if you’re looking for one here, you’ll be disappointed.
Glenn Block had an interesting post about the “spirit” of the ViewModel design pattern. If you haven’t read it yet, do yourself a favor and go do so. I’m not going to talk about his subject matter here, really, but there was a very interesting reply in this posting from Ward Bell who’s also got a blog that’s well worth reading. In the reply, Ward talks about simplifying XAML/WPF coding by using convention based programming. In particular, this paragraph in his response stuck out to me:
Maybe we shouldn’t be marking up Person.Name at all. Maybe, if we had an easy way to walk the XAML tree, we could automate the wiring of the binding by letting convention tell us that "Person.Name" is accessible from the ViewModel.
See, the thing is, we do have a way to easily walk the XAML tree.
I’ve been playing around with a couple of different convention based solutions to WPF programming, some of which will see the light of day in Onyx in the near future, hopefully. What I’d like to do with this blog post is explore the idea, describing a concept that could be implemented to do exactly what Ward wants. I’m going to discuss implementation details, but I’m not going to provide code. This is all theoretical and is being presented for discussion purposes.
Ward gives a use case where he has a TextBox that’s been provided an x:Name value. He then says “A one-line wizbang in the code-behind constructs the binding for us … and not just for this TextBox but for every control bound to a property of Person.” First, I don’t like the idea of needing a “one-line whizbang in the code-behind.” I’d propose that instead we rely on an attached property/behavior to do this. Onyx already has the perfect attached property for this: View.ViewModel. The change handler for this attached property can walk the tree to provide our convention based bindings. In WPF we can actually use a trick that would enable us to not even have to walk the tree manually. View.ViewModel in the WPF version of Onyx is marked as an inherited property, so we’ll get change notifications for every child element which means WPF has done the work of walking the tree for us. In Silverlight you’ll have a bit more work to do, and it may be a bit tricky to handle some timing issues, but it’s all very doable.
I’d like to discuss using x:Name as the hook to use for our conventions. I don’t like this, for a few reasons. First, the fact that x:Name creates backing fields for you is something that I don’t care for, unless your intention really is to have a backing field. Second, x:Name is meant to be unique, while there will be several scenarios where we don’t want to be restricted in this manner. So, I’d propose using a special attached property for our hook. I’m struggling with a good name for this one, but for now let’s just call it View.Moniker.
So, now we have everything that’s necessary to do data binding by convention instead of configuration. But we can carry this idea much further. Let’s say we have a Button that we’ve given a View.Moniker of “Save”. If we have a SaveIsEnabled property on our ViewModel, that should be bound to the IsEnabled property of the Button. If we have an OnSaveClicked method on the ViewModel, that should be added as an event handler for the Click event of the Button. If we have a SaveCommand property on the ViewModel, that should be added as a command binding on the Button. You can imagine several other conventions to adhere to, so this should be an extensible concept. Instead of hard coding the conventions, include an ApplyConventions (needs a better name) event that can be hooked into to apply the conventions required by the individual application.
So, what are your thoughts on this?