Papa's Perspective

MVVM in 5 Minutes

Learn MVVM fundamentals by building this simple Twitter app.

Want to see Model-View-ViewModel (MVVM) without all the "helpers"? Perhaps you thought I was kidding in my previous column, "Fundamental MVVM". Now, I love helpers for things like commanding, behaviors, messaging and locators. But I'm holding to my earlier statement that these things help MVVM, which is all about separation; they do not make MVVM. That's an important distinction.

I admit that with all the conversation about how to develop with MVVM it's sometimes difficult to separate what is MVVM and what's just a helper. That's one of the reasons I'm writing about these topics. I think it's important to make that distinction first. Once you understand MVVM, you can decide which helpers you want to use. Otherwise you may go down the MVVM path only to feel like you got blasted backward with a fire hose.

So let's take a look at MVVM with no frills. This sample app is going to be the Hello

World of our generation: a Twitter app that will look something like the image in Figure 1.

Figure 1. The image created by the TimelineView.xaml of a Twitter app built using the Model-View-ViewModel pattern.

Model
My Twitter app needs tweets to appear in the main timeline. So the first thing I do is create a Model called Tweet. The Tweet class inherits from a class I call Observable-Object, which simply implements the INotifyPropertyChanged (INPC) interface. INPC is a simple interface that implements a PropertyChanged, which is what a Model needs to communicate to a View's controls that something about a property has changed. I could've implemented the INPC interface on the Model directly but I never do that in the "real world," so why bother here. I like the base class ObservableObject because it simplifies this process.

The rest of my Model has a series of properties that describe the Tweet, such as UserName. All of the properties call the RaisePropertyChanged method (which is on the ObservableObject class):

protected const string UserNameProperty = 
"UserName";
private string _userName;
public string UserName
{
  get { return _userName; }
  set
  {
    if (_userName != value)
    {
      _userName = value;
      RaisePropertyChanged(UserNameProperty,  	        
        TitleProperty);
    }
  }
}

The Model is a simple representation of the data. It's separated into its own class because I may have more than one View where I want to display tweet information. The separation fosters the reuse of code.

ViewModel
The ViewModel class is built for a View. Yes, it can be used by more than one View, but let's not go off on what-ifs and other scenarios quite yet. For now, let's assume we have a ViewModel whose job is to expose the data points and presentation logic that a specific View needs. The TimelineViewModel class has a Tweets property, which is an Observable-Collection<Tweet> that aggregates a collection of instances of the Model class for the View in my sample app.

What's the main job of my ViewModel?

  1. Expose the Models needed by the View (Tweets or IsBusy, for example)
  2. Expose the logic needed by the View (RefreshTweets, for example)
  3. Handle any presentation logic

The ViewModel inherits from Observable-Object (which implements INPC), so all of its properties will let the View know when they change. This example just uses a single Model, but in many cases the ViewModel may aggregate multiple Model classes, which could even be object graphs. The ViewModel is built to handle customizing the exposure of the data for the View. What I mean by this is that the ViewModel can aggregate one or more Model classes and add other properties that the View may need. For example, my View may need to bind to properties such as IsBusy or LoggedInAsName, neither of which are in the Model Tweet. I can simply add these to the ViewModel as needed.

The ViewModel also handles presentation logic. One simple example of this is the job of making the call to go get the latest tweets and loading the Tweets property in the ViewModel. In my sample app I mocked this so it's not actually hitting the Twitter services, but the concept is exactly the same.

OK, quick pro tip: I like my ViewModel classes to direct the data manipulation calls; however, I abstract the calls to a data service, then out to its own class. In this example I would create a class called TwitterService and it would then make the API calls to Twitter. The ViewModel would just call the TwitterService class's GetTweets method. I find this abstraction really nice for three big reasons. First, it hides the Web service API calls from the ViewModel, which really could care less about how it gets its data. Second, the TwitterService class is now reusable by other ViewModel classes. Finally, this is really great for design-time data and for mock data when unit testing.

View
Now we get to the View, the final piece of the MVVM triad. My TimelineView has a ListBox that defines an ItemTemplate for displaying the individual tweets. Timeline-View is databound to the TimelineViewModel declaratively in the XAML. First, the ViewModel is created as a static resource:

<phone:PhoneApplicationPage.Resources>
  <local:TimelineViewModel x:Key="TimelineViewModel" />
</phone:PhoneApplicationPage.Resources>

Then the View is data bound to the ViewModel by setting the DataContext. In the sample app I do this in the outermost panel in the page, which happens to be the Grid:

DataContext="{Binding Source=
  {StaticResource TimelineViewModel}}"

Wrapping Up
When you run the sample app you'll see there are no additional references, no magic code, zilch, nada. Some of you may be asking how to hook up communication from the UI to the ViewModel, commands, behaviors, locators, dependency injection, Inversion of Control containers, messaging and dialogs. These tasks can certainly be done with MVVM. This column focuses on the fundamentals of MVVM. Of course, there are great ways to tackle all of those scenarios. But before we fly, let's walk. And that is Papa's Perspective.

About the Author

John Papa is a Microsoft Regional Director and former Microsoft technical evangelist. Author of 100-plus articles and 10 books, he specializes in professional application development with Windows, HTML5, JavaScript, CSS, Silverlight, Windows Presentation Foundation, C#, .NET and SQL Server. Check out his online training with Pluralsight; find him at johnpapa.net and on Twitter at twitter.com/john_papa.

comments powered by Disqus

Reader Comments:

Tue, Jul 17, 2012

This horrible program won't get anyone anywhere near understanding MVVM. It is a bad example of how to implement it, and should be removed from the net. Better still, the author should be barred from 'helping' the Community any further.

Wed, May 23, 2012 rajen Sydney

Thanks a lot John.

Mon, Mar 12, 2012

The zip file can not be unzipped with either WinZip 16 or Windows Explorer. Keep getting message saying it is an invalid file

Tue, Oct 18, 2011 John Papa Orlando, FL

Joel ... yes, that will do it for you. Anonymous ... You can refer to the diagram at the link: http://visualstudiomagazine.com/articles/2011/08/15/fundamental-mvvm.aspx If you wanted something else, let me know and I can work on it for a future post.

Sun, Oct 16, 2011

this helped to understand MVVM at a basic level. I think a good diagram would help even more. what helped most was to think of the VM as the model *of/for* the view.

Sat, Oct 15, 2011 Joel Zinn Tulsa

John, when you say load the phone tools 7.1 are you talking about Windows Phone SDK 7.1?

Wed, Oct 12, 2011 John Papa Orlando

Matt, Good question. It does not violate any rules, and I would argue that there are very few rules to begin with ... mostly guidelines. That said, some folks who use MVVM do what you are saying and they have the models NOT implement INPC and therefore they make the ViewModel implement INPC. If you do this, then when the VM changes a property, you need to synch it with the model (and vice versa). There is certainly more work involved in this approach, but is it OK? Sure. I prefer and recommend having the VM Model use INPC because its much less work, no synching issues with a VM, and is still not exposed directly to a View. The View is bound to the VM, and to a property on the VM that represents the model. Not the model itself. This is a very important distinction. It is still following separation. John

Tue, Oct 11, 2011 Matt

Doesn't this example violate the integrity of the layers? In other words, the model should never be accessible and/or touched by the view, and yet here were are exposing the model directly to the view. The model shouldn't have the responsibility of managing INPC -- that's the job of the ViewModel. So what seems to be missing here is the TweetViewModel.

Tue, Oct 11, 2011 Paul Gardner

That was it. Thanks!

Sat, Oct 8, 2011 John Papa Orlando, FL

Larry/Paul ... You need the Windows Phone Dev tools/sdk to run the sample project. I just set up a new PC and installed VS 2010, SP 1, and then the phone tools 7.1 and it works. Hope this helps

Fri, Oct 7, 2011 Becky Nagel Editor

Bad link at the top corrected! Our apologies.

Fri, Oct 7, 2011

"Fundamental MVVM" correct link is: http://visualstudiomagazine.com/articles/2011/08/15/fundamental-mvvm.aspx

Fri, Oct 7, 2011 Larry O'Heron Rochester NY

Concur with Paul. I can not open the project w/VS 2010 SP 1.

Thu, Oct 6, 2011 Paul Gardner

What version of VS is the sample code for? I tried to open in VS 2010 SP1 (10.0.4) and am being told that the csproj isn't supported by my version

Thu, Oct 6, 2011 anonymous

You provided a link to "Fundamental MVVM" (line 2, second word)... It is pointing to the wrong article.

Tue, Oct 4, 2011 John Papa Orlando

Philip & Bryan ... thanks for reading the article. This article was intended to be a primer, as I get asked a lot to provide a dead simple example with code. So that is what this is. I can most certainly provide more in depth features in future articles ... in fact I plan on it :) You have some other great ideas in your comments too. Thanks for the feedback ... I'll try to address some of them in the future.

Tue, Oct 4, 2011 Bryan Morris

I'm completely sold on MVVM, but I too would like to see some more in depth articles. Like something on how you would integrate the various types of Web/WCF services into an MVVM scenario. One example of a question I have concerns WCF RIA Data Services vs. some of the things Benjamin Day said in his article "6 MVVM Tips: Leverage ViewModel and Unit Test Silverlight and WP7 Apps". I'd also like to see an article that does a comparison of MVVM frameworks like MVVM Light and Simple MVVM. You could include things like how well they work in WPF, Silverlight, WP7, and Metro environments and what their future support will be.

Tue, Oct 4, 2011 Philip

Well, its another beginners article on MVVM, kudos for that :) I hope you follow it up with one that starts to delve into the mechanics you need to know to make MVVM truly usable for a production quality application; Commanding, VisualState and Mediator messaging IMO.

Add Your Comments Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.