In this post I'll talk about the toolkit I use and why I like it in MVVM projects. The other posts in this series are as follows (I'll update this list as they are published):
- Silverlight, MVVM & SharePoint - About this Series...
- Silverlight, MVVM & SharePoint - How I do MVVM
- Silverlight, MVVM & SharePoint - My favorite MVVM toolkit - MVVM Light Toolkit
- Silverlight, MVVM & SharePoint - Working with Commands
- Silverlight, MVVM & SharePoint - Working with Messages
- Silverlight, MVVM & SharePoint - Working with Dialogs
- Silverlight, MVVM & SharePoint - Testing the Business Logic
- Silverlight, MVVM & SharePoint - Testing the User Interface
- Silverlight, MVVM & SharePoint - Using Data Services
Generally speaking I'm not the type of developer that likes to hitch my wagon to a specific type of toolkit. In the years I've spent as an instructor, writer & speaker I've developed the opinion to be as vanilla as possible... don't force someone to jump on board some framework just because you like it.
I do have an exception though, and that's the MVVM Light Toolkit. If you've already elected to adopt the MVVM design pattern in building your XAML based applications, be it Silverlight or WPF, I personally don't think it's that much of a leap. What I like about MVVM Light Toolkit is that there is only one thing you really have to buy into & that's the ViewModelLocator. The rest of it is 100% optional.
The MVVM Light Toolkit was built & run by Larent Bugnion. It's free and is easy to implement in new projects (existing ones need a bit more work). The only gripe I have is the
lack of a really good installer (I was behind on my blogs... Laurent has an installer on his site now) and really good documentation. Most of the documentation is found on blogs & in forums like the mvvmlighttoolkit mvvm-light tag on StackOverflow.
Let me enumerate a few things WRT MVVM Light Toolkit.
When binding a view model to the view without a toolkit, you typically have to create an instance of the view model in the view's code behind constructor and attach it to the view's data context. That stinks as you want to keep all code out that isn't directly related to the view. The ViewModelLocator helps with this as it allows you to do this with declarative data binding. It contains an instance of each view model in your application as well as a static reference to it as well as shown by the following Class View of one from my Product Browser reference implementation (RI). Notice there's a static and non-static version of Main (which is my MainViewModel):
A new object, Locator is defined in the App.xaml file of your project effectively creating a global reference to the ViewModelLocator:
Now within your views you can easily bind to the view model declaratively as seen in this view's XAML:
The view model base is the base class you can use for all your view models. It contains a few helpful members such as the following that you don't have to implement yourself (perfect for the lazy productive coder!):
- RaisePropertyChanged - Good data binding means you'll almost always implement the INotifyPropertyChanged interface. Thankfully this implements it for you & hooks up to the MVVM Light Toolkit's messaging infrastructure with the optional broadcast flag.
- IsInDesignMode - Great property to have to figure out if you are currently in a design tool or running "live". Since tools like Expression Blend & Visual Studio are actually running your app when you look at it in design mode, this can help when working with live data.
This is one of the coolest things in the toolkit. Ever had a need where you want to effectively shout from one part of your app and have other parts of your app listen for these proclamations? Sure you could create events, but there's so much extra plumbing you have to do which just stinks & even worse, it's very hard to test. This is where the Messenger kicks in. It lets you listen for broadcast messages from one or more places in your app. You register the code to run as a delegate and that code runs only when a message of a specific type is broadcast in the Messenger stack. I'll spend more time talking about this in a later post in this blog series.
When creating commands you have to implement the ICommand interface which specifies the code to run when the command is fired (ICommand.Execture()) and the Boolean method that determines if the command can execute in its current state (ICommand.CanExecute()). The RelayCommand reduces the amount of code you have to write to create commands as it lets you pass in delegates instead of having to build up a whole class for each command. Perfect for the lazy productive coder!
Closely related to the RelayCommand, EventToCommand is a Silverlight behavior that you can use to fire your commands when the UI control you are using does not provide a command property to bind to. Thus, what you can do is bind the EventToCommand behavior to the control and then plumb any event to actually fire the command. Here's a sample of how you'd use one:
Last but certainly not least is the DispatcherHelper. All Silverlight network communication like calls to services happens on a background thread asynchronously. When you get the response, you need to jump back onto the primary thread to update properties that raise the PropertyChanged event. The challenge is that you have to figure out if you are on the correct thread before doing this. The DispatcherHelper does this for you. After it is initialized within the App.Application_Startup() method, you use it like so:
What that code is doing is calling a method that will save the selected product with a data service. This code runs asynchronously. The UpdateProduct method also accepts an Action which is effectively a delegate. I'm passing in some code that uses the DispatcherHelper that effectively says "if you're on the UI thread stay here and run this code, otherwise jump over to the UI thread and run the code."