With all the religion being built around commanding. Does it seem overly complex to anybody else out there? I have an approach that I came up with to use a custom behavior to simply enable binding of various physical events to specific View Model operations that need to be invoked.

I posted some code and sample project on how to get a Silverlight 3 Navigation Project up and running using MVVM and using absolutely no Commanding to get anything done.

1. Loosely coupling to operation

Commands are cool and technically the “right way” to do things. But imagine if you had to create a DependencyProperty for every property on your View Model. This is kind of being asked of us to implement Commands. You mean every publically exposed operation now has to have an ICommandProperty that implements some routed command. I have to do what kind of work to just invoke an operation from a random event on a control in my app?! And after all this it isn’t even blend friendly?!

Well here is another option. I created a custom behavior that simply uses Silverlight’s own data binding technique of using reflection to access members of the Data Context. BUT instead of invoking public properties, I am invoking public operations. Some might cringe but if you have a problem with this then you have a problem with regular old Property Binding too. This approach is no more tightly coupled than Property Binding and better yet, it is dead simple to use.

Follow these simple steps:

  1. Write a parameter-less POPO (Plain Old Public Operation…now its getting ridiculous :-)) on your View Model, let’s call it Save.
    public void Save() { ... }
    
  2. Whip open Blend, grab your button.
  3. Select InvokeViewModelMethod behavior from the behaviors list and drag it onto your button.
  4. Now Select Click as the event trigger and “Save” as the method name.
  5. That’s it. Now you are loosely coupled to your View Model with NO code-behind and your designers are happy because now they don’t have to dance around blend unfriendly things.

Next…let’s talk Navigation…

2. Navigating between screens declaratively

What’s great about Silverlight 3 Navigation is that you can use familiar URI based navigation and even pass query strings between pages. Thus shielding each page from the exact implementation of the other. One detractor to this approach is that, for all practical purposes, you can only pass primitive types safely. Technically there is nothing stopping you from using binary serialization and stuffing a full POCO up there but its not advisable.

The problem that you immediately run into when trying to build a MVVM Navigatable application is that you constantly have to write code behind to add query string parameters and as a result, you have to cast your View Model in order to grab properties on it. I created this HyperlinkWithParameterAction based on the HyperlinkAction TriggerAction inside Microsoft.Expression.Interactivity.Core. This little guy will take a single parameter and automatically wire up the query string for you by using reflection to grab properties off the View Model. In a future post I will enhance the code to take a collection of parameters.

Finally…we need to do some house keeping to make sure everything is playing nicely together.

3. Ensuring View Model manipulation happens on the UI thread

Inside the base view model class’ implementation of RaisePropertyChanged you can see that before performing invoking the PropertyChanged event it checks to see whether or not the calling thread is on the UI Thread or not. If its not on the UI thread then it uses Dispatcher.BeginInvoke in order to add the property change notification to the UI thread. This is really important because when our customer behavior is invoked it is no longer on the UI thread. Therefore, if we don’t do this, while the operation on the View Model may get called it will fall on deaf ears—in that, the View will not be notified that properties on the View Model have changed. Special Thanks to Jason Kerns for the nice bit of dispatcher work in the View Model Base.

4. NavigationService must be accessible to the View Model

Part of my base View Model implementation and interface that the actual views interact with is all about getting a NavigationService object into the ViewModel so we can use it to navigate between pages. This could be further abstracted and I will look into this further because I’m just not happy with the ViewModel knowing about something so View related. Right now I am thinking some sort of static proxy that could house a reference to the NavigationService as we only need to grab it once.

Here’s a sample project with all the code. Go check it out!