WPF/MVVM Quick Start Tutorial

Introduction

Assuming that you have a decent understanding of C#, getting started in WPF isn't too difficult. I started looking at WPF a while ago, and didn't find many helpful MVVM tutorials. Hopefully this article addresses that.

As with learning any new technology, you get the benefit of hindsight. From my perspective, almost every tutorial on WPF I've come across is inadequate for one of several reasons:

The example is all in XAML.

The example glosses over the key facts that would actually make your life easier.

The example tries to show off WPF/XAML's capabilities with lots of pointless effects that aren't helping you.

The example uses classes that have properties that appear far too similar to framework keywords and classes, and are therefore difficult to identify in the (XAML) code as being user defined (the ListBox GroupStyle's Name attribute is a complete headache for novices).

So to address this, I've written this based on what I would have liked to have found as the #1 hit on Google after typing 'WPF Tutorial'. This article may not be 100% correct, or even do things 'the one true way', but it will illustrate the main points that I wish I had found in one place 6 months ago.

I will quickly introduce some topics, then show an example that explains or demonstrates each point. Accordingly, I haven't really attempted to make the GUIs pretty, that's not the point of this article (see the bullet points above).

As this tutorial is quite long, I've elided quite a lot of code for brevity, so please download the attached zip file, and look at the examples (.NET 4.0/VS2010). Each example builds on the previous one.

The Basics

The most important thing about WPF is data binding. In short, you have some data, typically in a collection of some sort, and you want to display it to the user. You can 'bind' your XAML to the data.

WPF has two parts, the XAML which describes your GUI layout and effects, and the code-behind that is tied to the XAML.

The neatest and probably most reusable way to organise your code is to use the 'MVVM' pattern: Model, View, ViewModel. This has the aim of ensuring that your View contains minimal (or no) code, and should be XAML-only.

The Key Points You Need to Know

The collection you should use to hold your data is the ObservableCollection<>. Not a list, not a dictionary, but an ObservableCollection. The word 'Observable' is the clue here: the WPF window needs to be able to 'observe' your data collection. This collection class implements certain interfaces that WPF uses.

Every WPF control (including 'Window's) has a 'DataContext' and Collection controls have an 'ItemsSource' attribute to bind to.

The interface 'INotifyPropertyChanged' will be used extensively to communicate any changes in the data between the GUI and your code.

Example 1: Doing It (mostly) Wrong

The best way to start is an example. We will start with a Song class, rather than the usual Person class. We can arrange songs into Albums, or one large collection, or by Artist. A simple Song class would be as follows:

In WPF terminology, this is our 'Model'. The GUI is our 'View'. The magic that data binds them together is our 'ViewModel', which is really just an adapter that turns our Model into something that the WPF framework can use. So just to reiterate, this is our 'Model'.

Since we've created a Song as a reference type, copies are cheap and light on memory. We can create our SongViewModel quite easily. What we need to consider first is, what are we going to (potentially) display? Suppose we just care about the song's artist name, not the song title, then the SongViewModel could be defined as follows:

Except that this isn't quite correct. Since we're exposing a property in our ViewModel, we would obviously want a change to the song's artist name made in the code to be automatically shown in the GUI, and vice versa:

Clicking the button does not update anything, because we have not completely implemented data binding.

Data Binding

Remember I said at the start that I would choose a property that stands out. In this example, we want to display the ArtistName. I chose this name because it is NOT the same as any WPF attribute. There are a countless number of examples on the web that choose a Person class and then a Name attribute (the Name attribute exists on multiple .NET WPF classes). Perhaps the authors of the articles just don't realise that this is particularly confusing for beginners (who are, curiously enough, the target audience of these articles).

There are dozens of other articles about data binding out there, so I won't cover it here. I hope the example is so trivial that you can see what is going on.

To bind to the ArtistName property on our SongViewModel, we simply do this in the MainWindow.xaml:

<LabelContent="{Binding ArtistName}"/>

The 'Binding' keyword binds the content of the control, in this case a Label, to the property 'ArtistName' of the object returned by DataContext. As you saw above, we set our DataContext to an instance of SongViewModel, therefore we are effectively displaying _songViewModel.ArtistName in the Label.

Once again: clicking the button does not update anything, because we have not completely implemented data binding. The GUI is not receiving any notifications that the property has changed.

Example 2: INotifyPropertyChanged

This is where we have to implement the cunningly named interface: INotifyPropertyChanged. As it says, any class that implements this interface, notifies any listeners when a property has changed. So we need to modify our SongViewModel class a little bit more:

There are several things now happening here. Firstly, we check to see if we are going to really change the property: this improves performance slightly for more complex objects. Secondly, if the value has changed, we raise the PropertyChanged event to any listeners.

So now we have a Model, and a ViewModel. We just need to define our View. This is just our MainWindow:

This is ok, but it is not how we should use WPF: firstly, we have added our 'update artist' logic into our code-behind. It does not belong there. The Window class is concerned with windowing. The second problem is, suppose we want to move logic in the *button* click event to a different control, for example, making it a menu entry. It means we will be cut'n'pasting, and editing in multiple places.

Here is our improved view, where clicking now works:

Example 3: Commands

Binding to GUI events is problematic. WPF offers you a better way. This is ICommand. Many controls have a Command attribute. These obey binding in the same way as Content and ItemsSource, except you need to bind it to a *property* that returns an ICommand. For the trivial example that we are looking at here, we just implement a trivial class called 'RelayCommand' that implements ICommand.

ICommand requires the user to define two methods: bool CanExecute, and void Execute. The CanExecute method really just says to the user, can I execute this command? This is useful for controlling the context in which you can perform GUI actions. In our example, we don't care, so we return true, meaning that the framework can always call our 'Execute' method. It could be that you have a situation where you have a command bound to button, and it can only execute if you have selected an item in a list. You would implement that logic in the 'CanExecute' method.

Since we want to reuse the ICommand code, we use the RelayCommand class that contains all the repeatable code we do not want to keep writing.

To show how easy it is to reuse the ICommand, we bind the Update Artist command to both a button and a menu item. Notice that we no longer bind to Button specific Click event, or Menu specific Click event.

Example 4: Frameworks

By now, if you have read closely, you'll probably notice that a lot of this is just repetitive code: raising INPC, or creating commands. This is mostly boilerplate, and for INPC, we can move it to base class that we call 'ObservableObject'. For the RelayCommand class, we just move that into our .NET class library. This is how all of the MVVM frameworks you find on the web begin (Prism, Caliburn, etc.).

As far as the ObservableObject and RelayCommand classes are concerned, they are rather basic and are the inevitable result of refactoring. Unsurprisingly, these classes are practically the same as those by Josh Smith.

So we move these classes into a small class library that we can reuse in future.

The view looks much the same as before:

Example 5: Collections of Songs, Doing It Wrong

As I said before, in order to display collections of items in your View (i.e. the XAML), you need to use an ObservableCollection. In this example, we create an AlbumViewModel, which nicely collects our songs together in something that people understand. We also introduce a simple song database, purely so we can quickly produce some song information for this example.

In this example, clicking 'Add Artist' works fine. But clicking 'Update Artist Names', fails. If you read the yellow highlighted note on this page on MSDN, it explains why:

To fully support transferring data values from binding source objects to binding targets, each object in your collection that supports bindable properties must implement an appropriate property changed notification mechanism such as the INotifyPropertyChanged interface.

Our view looks like this:

Example 6: Collections of Songs, the Right Way

In this final example, we fix the AlbumViewModel to have an ObservableCollection of SongViewModels that we created earlier:

Now all our buttons that are bound to commands operate on our collection. Our code-behind in MainWindow.cs is still completely empty.

Our view looks like this:

Conclusion

Instantiating Your ViewModel

One last point that is worth mentioning is that when you declare your ViewModel declaratively in the XAML, you cannot pass it any parameters: in other words, your ViewModel must have an implicit, or explicit default constructor. How you add state to your ViewModel is up to you. You may find it easier to declare the ViewModel in the MainWindow.cs code-behind, where you can pass in construction parameters.

Other Frameworks

There are lots of other MVVM Frameworks of wildly different complexity and functionality, targeting WPF, WP7, Silverlight, and any combination of the three.

Finally...

Hopefully these six examples show you how easy it is to write a WPF application using MVVM. I've tried to cover all of the points that I think are important and often discussed in multiple articles.

If you find this article helpful, please feel to vote it up.

If you find faults in this article, or I've said anything wrong, or you have some other issue with it, please leave a comment below explaining why, and how you would fix it.

References

I've tried to abide by various agreed .NET programming guidelines and styles whilst writing this. A list of references I used whilst compiling this article are listed here:

Further Reading (Gratuitous Links)

Following on from this, I have added two further CP articles on using
Laurent Bugnion'sMVVM Light Framework which I recommend you start using as you to get to grips with MVVM for the first time. If you understood this article, move on to:

Comments and Discussions

When you wrote your opening comments, it was as if they were coming from my own thoughts. If you are trying to teach a topic to beginners on a subject don't complicate matters with other subjects and very very clear on naming conventions so as not confuse readers.

You have easily saved me days worth of sifting though other (less optimal) tutorials.

Thanks - if you're referring to using private fields in the view model, then that is so that we only raise INPC on properties and assign _variable = value when _variable != value to avoid a redundant assignment (imagine if we do a redundant assignment hundreds of times, we'd raise the INPC event hundred of times potentially slowing down the gui).

This is definitely the best MVVM example I have read so far, and I have finally come to understand some key ideas behind (e.g. Command, INotifyPropertyChanged). However, I would still recommend people who are completely new to MVVM (like me one week ago) to read other simple MVVM examples first/at the same time, because some concepts were not elaborated in great detail here (I think Barry intended to do this to keep the article clean). Finally, I would say that the sample app is great and easy to follow! THANK YOU!

Hello, I would like to express my sincere thanks for the nice job u v done for us.
I started learning Prism/WPF and MVVM from Microsoft Best Practices, but u r explanation gives detailed clue to the extent that even a layman can understand easily. LOL!
I have a project and would like to communicate with u so as I can learn more from you.

Thank you very much! I have scoured the web looking for an example explanation for weeks to implement an Mvvm pattern, but one that explains a step by step implementation as I am quite new to implementing WPF properly. My very first implementation was wrong i.e. winform style. So to change that mindset from winform to WPF was not as easy as I thought it would be for me.

Your article has FINALLY made WPF and Mvvm "click" so to speak for me!