Technical debtWhy does maintainability matter? Maintainability is not the inverse of complexity. That’s because complexity can be controlled with good patterns like MVVM. But without good patterns, complexity is the logarithmic multiplier to headaches and troubles. I don’t mind picking up on a project that is well organized. I hate even smelling projects that have deep architectural debt.
Third party librariesIt’s important to recognize that there are many high-quality, third party libraries out there to help developers build out MVVM solutions (like MVVM Light, nRoute). They are great. And, developers should not hesitate to adopt them if they like. Because I like to type, I tend to write my own similar framework with /just/ the code I need and nothing more. I like that. But the frameworks are fine, too.
Native MVVMLook, there is no MVVM template. There is no MVVM base class. But there are plenty of conventions and plenty of framework candy to help MVVM implementations sail simply. XAML developers love MVVM, in fact, MVVM was invented by the original WPF creators. To that end, MVVM is lightweight, simple, and easy to learn.
Separation of codeMVVM is not an exercise to remove all the code from your XAML code behind files. Instead, MVVM intends to separate the logic you need to access and interact with your data from the logic you need to interact with your UI. For example, loading your data, validating your data, manipulating your data, and saving your data – that’s all part of the View Model. Conversely, running animations, responding to gestures, and adding the bling that makes your app stand apart – that’s part of the View.
Typical mistakesCreeping logic into your code behind – it is not uncommon for developers to enjoy the simplicity of double-clicking Visual Studio’s designer and letting a click event handler be created for you. This is where RAD development really blooms. However, even if you only interact with the View Model in that handler, logic intended for data interactivity should be constrained to the View Model. In the video below, we will see how ICommand allows developers to stop implementing click handlers and start referencing the logic in their View Model.
In order to offend the purists, I have to add this: sometimes you have to have code behind – even when you are manipulating the data. Reality is, you want to minimize it. Fact is, you can’t always eliminate it. That doesn’t mean you should not try.Creeping logic into your view model – it is not uncommon for developers (especially those new to MVVM) to get a little carried away with what they put in their View Model. For example, animations unique to the View belong in the code behind of the view. That logic /could/ be included in the View Model, but you need to start training your brain to separate code from data logic to interaction code.
Let’s take a look
In the video above, I build out a real scenario for using MVVM, not only to fetch and avail the data in your application but also to interact with user actions by implementing ICommand within the View Model. The CommandDelegate (get it here) contains the Execute function which implements the action itself. This is disabled based on the CanExecute in the same class.
MSDN: Older versions of Microsoft .NET Framework reference documentation indicate that the System.Windows.Input.ICommand interface is defined in PresentationCore, which is a Windows Presentation Foundation (WPF) assembly. That is no longer the case,System.Windows.Input.ICommand is defined in the System.ObjectModel assembly, so you don't need to take WPF dependencies in order to implement ICommand.
Some handy tips
- Some developers like to make their View Model a singleton and reference it statically. I have done this, too. It allows you to reuse a View Model in different views without worrying about the cost of constructing it. This can also be overkill, so only do it if you need it.
- In WPF, CanExecute is called constantly. As a result, it could be a performance impact if the logic is costly. In WinRT, CanExecute is only called when CanExecuteChanged is raised. In my implementation, you will see, this event is manually raised by the View Model.
- It is common to create a base View Model. This can consolidate repetitive logic to a single chunk of code. It can also allow you inherit into a design-time view model which you reference for the sake of development but that is unused at runtime. I have also done this – almost every project.
- Snippets in Visual Studio help developers encapsulate common, recurring code into reusable chunks. In this article, I wrote about propnote. This is my favorite snippet – and one I add to Visual Studio every time I install it. It is a XAML developer’s best friend, as far as I am concerned.
MessagingOne thing I did not communicate was messaging. In MVVM, messaging is simply events raised inside the View Model that are handled in the View. This let’s the View Model “send a message” so some UI action is performed that is out of scope of the View Model. This approach is very common in projects where the View Model is in a different project where the UI thread is inaccessible.
Best of luck!