A few folks asked me to provide a ViewModel sample of some sort. I thought this was a great idea, since I don’t know that I had seen a straight-forward ViewModel sample yet. So here it is: HelloWorld.ViewModel!
Let’s start out by looking at the code for the ViewModel class, since that’s the file that I authored first.
The takeaways from this class:
- It’s a POCO
- It implements System.ComponentModel.INotifyPropertyChanged so that we can bind to its properties
- That’s it
- Oh yeah, no UI knowledge – That’s important!
Now for the other side of the coin, the View.
What the View exhibits:
- Instantiates a VisibilityConverter for later use
- Instantiates the ViewModel declaratively, using the <app:HelloWorldModel /> tag; and assigns this ViewModel instance to be the DataContext of the UserControl (and all child controls)
- Declares 2 images, Smiley.jpg and Sad.jpg, and binds their Visibility properties to the IsHavingGoodDay property on the ViewModel. Notice the VisibilityConverter use and the ConverterParameter. This allows a single boolean to drive 2 different controls, with opposite behavior. The VisibilityConverter is a custom IValueConverter I wrote. I’ll do a post on it later.
- Binds a TextBlock to the Greeting property on the ViewModel.
- Binds the textbox and the checkbox to the ViewModel using TwoWay binding.
Now, let’s look at the code-behind for the View. This is by far the most important part of this sample.
Yep, (essentially) no code in the code-behind. And yes, that is the most important part of the ViewModel pattern. You can have your View bound to your ViewModel using 1-way and 2-way binding, with logic in your ViewModel and not a lick of logic in your View’s code-behind.
As I mentioned in my ViewModel Pattern introductory post, it’s important to disallow any view-specific behavior from leaking into the ViewModel. The visibility of the two images in this sample are perfect examples of this point. The ViewModel exposes a boolean, not a Visibility property. The View can then do whatever it wants with that boolean. For all the ViewModel knows, the View doesn’t do anything with it, but in this case, there are 2 images that are toggled based on the value.
In future posts, I’ll talk about more ViewModel details that go beyond Hello World type applications. Most notably, I’ll be writing about service references and how a ViewModel should get data from services to be exposed to the View. Keep in mind that this pattern can be applied in either WPF or Silverlight.
You can download the source code for this application here.