Better User and Developer Experiences – From Windows Forms to WPF with MVVM: Part 7, MVVM

I mentioned in the introduction that a new architectural pattern has emerged for Windows Presentation Foundation: Model-View-ViewModel.  As I mentioned, MVVM can make developing applications in WPF efficient, quick, and highly maintainable.  Now that I’ve covered some of the basic technological advances in WPF, mainly Data Binding, Commands, and Templating, it’s time to bring everything together, and demonstrate how this improves our jobs as developers.

As I mentioned in the section on templating, WPF’s design strives to maintain a clear separation between presentation and logic.  We’ve seen some of the advantages in terms of control creation – unlike Windows Forms, we can completely change the way a control looks merely by creating a new template, using XAML in a completely declarative form.  No code is required.  We get more flexibility with less work.  By separating presentation and logic, WPF creates opportunities for much greater degrees of flexibility in our applications.

As a developer, I see this as a very “good thing”.  The Model-View-ViewModel pattern has one goal – to extend this same flexibility into our applications by creating and maintaining a clean separation of concerns through our entire application.

In order to understand MVVM, I will start off by defining our distinct concerns, the individual “parts” of our application. 

I already defined our arguably most important concern: the Model.  Again, the Model is the domain-specific data and logic used within your application.  It’s the goal – the “data” you’re working to expose to your users.  This may be customer records in a database, or product information on a website, or anything else.  In our case, it’s two classes, the Feed and the FeedItem class.  In Model-View-ViewModel, our goal is to keep the model unaware of the specific application or technology that’s using it.  The Model knows about itself, and nothing else.

The second concern I’ll discuss is the View.  The View is the entire user interface of your application – it’s everything the user’s interact with directly: every control, every button, every check box, every window.  As I mentioned in part 3, WPF changes how the View is normally defined.  Instead of developing the user interface via code, we use XAML to create an XML-based, declarative description of the interface.

Let’s review our goal of maintaining a full separation of presentation and logic, this time just in terms of the View.  When we create our user interface, we want to define what the user will see (presentation) without worrying about how the program works (logic).  XAML is perfect for this, as it lets us design the user interface with zero code involved.  This gives us an easy way to think about our View in terms of our goal: The user interface should be declared entirely in XAML, with zero code behind.

Succeeding in this goal has many advantages.  It makes the View very flexible – a designer can take our View and stylize it or change it in any way desired, without changing or effecting a single line of code.  Also, if there is no logic in the View itself, it eliminates the risk of “stale” or unused code creeping into the View, which often happens in Windows Forms.

Now that we have the View and the Model defined, we need a way to hook the two things together.  Something has to coordinate our actions between the Model and the View, so that the user’s interaction has an effect on the Model.  This is handled by our third concern: the ViewModel.

The ViewModel serves the purpose of adapting the Model to be directly usable by the View.  In order to do this, we take advantage of WPF’s incredible Data Binding support.  In MVVM, the ViewModel sits between the View and the Model, and basically acts similar to an Adapter – it translates the properties and methods of the Model to a form that can be directly used via Data Binding.

The ViewModel also provides us a place to manage application state and logic.  By taking advantage of WPF’s Commanding Infrastructure, we can define ICommand instances in the ViewModel that the View can directly access via Data Binding.  This provides us a clean way to keep the logic out of the View – again, the View works completely via Data Binding to the ViewModel.  This provides a means by which we can hook into logic from the View without having the logic be tied to the specific view that is using it.

Here is a diagram illustrating our three areas of concern:

MVVMThere are some important aspects of this diagram I will discuss, for each of our Concerns, some critical points

  • The Model
    • The Model is unaware of anything except itself
    • The Model could be used by any form of program, and is not tied to a specific framework or technology
  • The View
    • The View is defined entirely in XAML
    • The View only needs to know what to bind to, by name.  It does not need to know anything about what will happen when properties change or commands are executed.
    • The View’s state is completely based upon data binding
  • The ViewModel
    • The ViewModel knows nothing about the View
    • The ViewModel directly interacts with the Model, in order to expose it for data binding
    • The ViewModel manages the Application-specific information

The advantages here are profound:

Our Model, since it is self contained, can be used in any way we wish.  If, later, we decided we needed a web-based API to the same model, we could use the Model unchanged.  If the successor to WPF comes along, and we need to update our application to use it, the Model remains unchanged.

Our View, since it has no logic, is completely designable.  The View can be modified by a designer with little or no programming experience, with no fear of breaking the logic.  The only knowledge that the designer needs to know is what properties and commands are available, and their names – everything else is handled directly by the framework to make it work.  This leads to a tremendous amount of flexibility in the View – the entire look and feel of an application can be changed at any time.

Our ViewModel gets a nice advantage from this architecture, as well.  Since it is not tied to a specific View, it is very easily testable.  The logic of our application is all exposed through self-contained ICommand implementations, which are easy to test.  The data is exposed via properties; again, easy to test.

There is still one issue left to resolve, though.  At this point, we know how to architect a single window or form correctly – the Model is used by the ViewModel, and the View “hooks” into the ViewModel with data binding.  This works great for a single user control – but we still need to create and wire up the controls in the first place.

At first glance, it seems like we’d need to know about the View and the ViewModel in order to do this.  For the ViewModel to be used as a binding source, it needs to be set as the DataContext of the correct View.  We need a way, given a ViewModel, to construct a View and set its DataContext.  In order to do this, we break one of our rules – the ViewModel, in order to construct the View, needs to know about the Views.

WPF, again, provides us with the final tool required for MVVM: Templating.  The same mechanism that our ListBox used when we discussed templating can be used for our ViewModel.  Instead of trying to construct our View, we can setup a simple DataTemplate that specifies that our View is used to render our ViewModel.  This will look similar to:

<DataTemplate DataType="{x:Type local:OurViewModel}">
    <local:OurView />
</DataTemplate>

This DataTemplate tells WPF that, any time we say to directly render an instance of OurViewModel, it should construct an instance of OurView, place it at that location, and set the DataContext of the OurView instance to the instance of OurViewModel.  Basically, WPF will do all of the work for us, just be specifying a DataTemplate.

Since DataTemplates are definable in XAML, and will propagate downwards through the Visual Tree in WPF, this lets our View automatically set itself up.  All that needs to happen is to provide a ContentPresenter in our View which binds, using standard DataBinding, to a ViewModel, and WPF will do all of the plumbing for us!

WPF adds three profound features: Data Binding, Commands, and Templates.  By using these three feature sets appropriately, we can redesign the architecture of our applications by using the Model-View-ViewModel pattern. This maintains a clear separation of concerns, allows for easy changes and redesign of the View, provides good testability, and keeps our domain specific classes completely isolated.

… Continued in the Conclusion …

About Reed
Reed Copsey, Jr. - http://www.reedcopsey.com - http://twitter.com/ReedCopsey

Comments

30 Responses to “Better User and Developer Experiences – From Windows Forms to WPF with MVVM: Part 7, MVVM”
  1. Pete says:

    When I first scanned this,what stood out to me was this bold quote:

    “The user interface should be declared entirely in XAML, with zero code behind.”

    While I agree that one should keep most logic out of the code-behind, I disagree that there should be zero code there.

    View-specific code is ok to have there. That is, code that exists solely to perform a view function, such as building an animation or something, or setting up a relationship between two elements in a view when perhaps that is cumbersome to do in xaml, can be in the view.

    Putting something into a specific visual state in response to a message from the VM is, perhaps, another case. Typically (99%) you’d handle that with binding, but that’s not always a reasonable route to take.

    Other view code could be for things like displaying a file dialog. Displaying a file dialog is really a view function. Dealing with the results of the dialog should happen elsewhere. If not displayed there, you’re stuck doing something like displaying UI from the ViewModel, which is equally bad, if not worse, than having code in the view.

    In practice, most apps will not need code in the code-behind, and most code folks are tempted to put there really shouldn’t be there, but I’d rather not be dogmatic about it :)

    Pete

  2. Reed says:

    Pete,

    First off, I was suggesting that the goal should be to have zero code in the code behind – not necessarily that it is an absolute, hard rule.

    That being said, I do agree that there are times when it’s reasonable to have code in the code-behind. However, in my experience to date, I’ve yet to find a single instance where there wasn’t a more elegant approach. Typically, I’ve found that, when I need code in the code behind file, it’s nearly always handled more elegantly, and more reusably, by creating an attached property or (Expression Blend SDK-based) Behavior, or by using some form of dependency injection/service (I use MEF for this) to handle the creation from within the ViewModel.

    Personally, I think displaying a FileDialog is a function of the ViewModel – not because of the dialog (which I agree is View, but could easily be provided via a service), but because the processing of a file dialog is logic that needs to be tested, and having that as part of a command or a method in the ViewModel makes testing much simpler.

    Anyways, thank you very much for your comments!

    -Reed

  3. Pete says:

    Thanks Reed. I appreciate the clarification.

    I love this series, BTW.

    On file dialog: One test I have mentally for what belongs in a viewmodel is “if I changed view technology, would it still apply”. I agree that a services is probably a better approach there.

    Many Silverlight folks look to WPF thought leaders for information on patterns like MVVM. Until very recently, they had to do things differently due to limitations in the platform. Often times, that meant some small amount of wire-up code in the code-behind. I agree that in WPF it’s harder to justify since the platform is more complete.

    Pete

  4. Reed says:

    Pete,

    Very good point re: Silverlight vs. WPF. I definitely see how the limitations in Silverlight, especially prior to SL 4, would make it so having View related code is “less bad” than the alternative hoops you’d have to jump through to avoid it.

    Mostly, my goal here was to get people coming from Windows Forms (ie: writing desktop apps) to think differently, so I’m really focused on WPF over Silverlight. I’m trying to explain the why behind the pattern, as well as what specifically makes it work in WPF. It’s something I feel has been lacking in all of the (very excellent) MVVM articles I’ve read to date… For a Windows Forms developer, putting code in the code behind is natural – trying to break that habit is probably the most important hurdle to jump through in moving to WPF, in my opinion.

    Thanks for the feedback! I really appreciate it.

    -Reed

  5. Robert says:

    Thanks Reed, this has been an outstanding series of articles on a subject I find quite fascinating. I’ll be following along for more.

  6. zamesking says:

    Great stuff, I got time to read your mvvm articles after my vocation. reed, I got a problem at hand now, I can not find an elegant solution for how to two-way bind the selectedItems in ListBox to the datasource in my viewmodel. Did you have any suggestions?

  7. Reed says:

    zamesking,

    Here’s an article describing one approach. Using SelectedItems is tricky, though.

    http://bit.ly/alNF72

    -Reed

    • zamesking says:

      Reed,

      Thanks for the reply, but I can not open the link in my country. Would you please copy the text, and send it to my mail box?

  8. Kate says:

    Hello Reed,

    Excellent work! As a beginner I was looking for some good tutorial on WPF-MVVM and stumled upon your blog….lucky me!! Your series really helped me in understanding basic concept of this framework and architecture pattern.

    One question: Do you have similar series/example for using MEF with a WPF-MVVM application? If so it would be really greate if you can share!

    Keep up the good work!!

  9. Bill says:

    This is a great series on WPF and migrating from WinForms. But I’m still having trouble not doing GUI in code-behind.

    Take a simple Circular Gauge Control I made in Silverlight (dstechlabs.com/cc). The font sizes I choose are directly proportional to the Diameter (DependencyProperty) of the gauge. And the placement of other child components are also mathematically related to Diameter. And if I use IConverters for all these placements, then I’m doing these calculations in code anyway, not XAML.

    Also, the short and long ticks at the edge of the gauge are made by looping thru angles and using trig functions to get their endpoints. Also, the number of ticks (the step size between angles) is proportional to Diameter.

    There just seems to be too many situations where sizing decisions can’t be made in XAML. For example, suppose I want a TextBox to be 3 times the width of the text rendered in a TextBlock. I don’t know this size until it’s rendered.

    I guess I’m missing something in my understanding of WPF’s View.
    Thanks for shedding any light on this for me.

    –Bill Daniels

    • Reed says:

      Bill,

      There are actually two issues here.

      For the first – the gauge control – I’d actually argue that this, being a control, is entirely, 100% View. Custom controls really fall outside of the realm of MVVM entirely, as they’re a resource that will be used later to implement the View in MVVM. I would, personally, actually use code behind to implement a custom control such as this, as it’s far simpler than trying to separate this out in many cases.

      Now – your second – the sizing situations example. This, to me, seems like a perfect case for a custom IValueConverter. The advatange here is you can make a converter to handle sizing, and reuse the converter in XAML with various values (ie: different sizing ratios) whenever needed.

      In my opinion, this fits in MVVM perfectly – you’re writing code, but the code is a reusable block of code (unrelated to your domain/application specifically) that can be reused as needed throughout your application. The code isn’t “domain specific logic”, but rather some additional functionality that can be used by any View, in any application.

      -Reed

      • Bill says:

        Of course the gauge control is 100% View – it’s GUI stuff. My point was having to do most of it in code and not XAML, when MVVM says the “View” stuff is supposed to be done in declarative XAML.

        Also, implementing 50 or more IValueConverters, once again in code, proves cumbersome to say the least, when doing all these calculations in a loop in one method, say on a ControlLoaded event, seems the most efficient implementation. Never mind easier to follow and maintain. (I also don’t see any way of looping in XAML. For example, draw a Border ‘n’ times).

        So what exactly “fits” the MVVM model here when 95% of doing this GUI is in code? How is declaring the View (GUI stuff) in XAML supposed to make these things easier for a development team?

        –Bill

        • Reed says:

          Bill,

          When making your Gauge control, you really shouldn’t be thinking MVVM – it doesn’t apply when writing a control, as you’re writing pure view code. I’d use code behind here – I wouldn’t do IValueConverters for writing a control, but rather reusable ones for writing an *application that uses the control*. When writing a control, you’re pure View, and you’re really completely outside of where MVVM applies…

          -Reed

          • Bill says:

            Okay, so my “View” team of developers is writing what my customers see (the GUI stuff which, of course, includes controls). But they’re not doing what the first “V” in MVVM stands for. They’re “completely outside” of that. Got it. Wow.

            Only Microsoft could have come up with such a Unified Model that makes so much sense.

          • Bill says:

            What’s the difference between “View” and “Pure View”? Are my Pure View coders not my View Coders?

          • Reed says:

            Bill, the way I would think of it is this:

            If you’re working on code that interacts with your business logic, and is specific to your application at hand, MVVM is appropriate.

            If you’re making a reusable control that’s intended to be used within the View layer from any application, your code is really “pure View” related, and MVVM doesn’t really apply. In this case, there is no Model, which means a ViewModel doesn’t make sense (its purpose is to bridge between the View layer and your Model).

            The same is true in Windows Forms – When writing a custom control, you don’t necessarily think in terms of architectural patterns like MVP, but rather making a single, reusable component.

          • Bill says:

            Thanks for your thoughts, Reed. I think I’ll wait for the “next” Development Model that handles both situations. IMO, MVVM has a gaping hole.

  10. Rohit says:

    First of all thanks for writing the series, I really enjoy reading your post especially on TPL.
    One question that came to my mind after reading this series is – MVVM is a pattern used in Presentation Layer right?, so model in MVVM in it’s entirety is not exactly the core that holds domain/business-logic, rather there must exist a dotted line from this model in MVVM to the business layer. Can you please shed some light on this?

    Best Regards,
    Rohit

    • Reed says:

      Rohit,

      MVVM is not just about the presentation layer – it’s the overall architectural pattern.

      The “Model” in MVVM is the same core model that’s holding your domain/business logic. The ViewModel is where you’d put any application specific bridge code that’s required. It’s purpose is to take your Model and expose it to your presentation layer (View).

      One of the main goals with MVVM is to keep the “Model” pure – you should be able to use your direct business logic and domain data without change. The ViewModel is where you place the code required to adapt your model for presentation.

      -Reed

  11. Rob says:

    In MainView.xaml, you bind the browser to the URI property of the MainViewModel and you update the value of the URI whenever the FeedViewModel_PropertyChanged event fires. This results in the Feed URI text control at the top of the window also updating. This doesn’t really cause a problem unless the Load RSS Feed button is pressed again without typing in another URI.

    What is the proper/best way to fix this? I believe you could add a CurrentItemURI property to the MainViewModel class and update and bind to that instead of the URI property. Alternatively, you could bind to FeedViewModel.SelectedFeedItem.Link (and not update the URI property).

    Thanks,

    Rob

  12. James says:

    Just read this great series as I wanted to try and start using WPF properly, I pretty much started by copying my Windows Form app, which works, but doesn’t quite seem right – this has definitely helped me rethink my app.

  13. Nero says:

    Thanks, Reed for this great series. For an amateur like me, it really helped a lot to get a clear picture of WPF and MVVM. “The ViewModel knows nothing about the View” – was very much comforting, but when you say ” In order to do this, we break one of our rules…” – it brakes my heart. I always try not to break rules. Doesn’t “…the ViewModel, in order to construct the View, needs to know about the Views” – create more coupling between the View and the ViewModel, which is a bad thing? Pardon my ignorance, but the way DataTemplate is used to relate the ViewModel to a View, i just didn’t understand how it makes the ViewModel to know about the View? I hope you’ll elaborate a bit. Thanks.

    • Reed says:

      Nero – If you read just past there, you’ll see that DataTemplates provide a way to avoid breaking the rule there. The View can effectively be created for a VM without any coupling. The “View” still needs to know what it’s for (to create the template), but then the VM no longer needs knowledge of the view at all.

  14. Adam says:

    This is one of the very best series on MVVM. Thank you. I’m excited to try it.

    Can MVVM support interfaces with multiple windows? If so, how? I don’t see a way to do this without putting code in the xaml codebehind, but I don’t know if this is so bad. It’s part of the View’s design to open a new window for some reason, the ViewModel shouldn’t care. So adding this kind of code to the codebehind shouldn’t break MVVM. What are your thoughts?

    • Reed says:

      It definitely can support this – though multiple windows is becoming less popular with modern development. There are many options for approaches – services and DI can be a common approach, as you can have a service used to decouple opening the window from the VM layer. Code behind isn’t necessarily bad – I see it as a pragmatic balance there: sometimes just putting some view code in code behind is far simpler, at which point, I’ll just go for it. This is especially true in smaller projects.

Trackbacks

Check out what others are saying about this post...
  1. […] This post was mentioned on Twitter by Reed Copsey, Jr., Caspar Kleijne. Caspar Kleijne said: RT @ReedCopsey: Blogging about moving from WinForms to #WPF with #MVVM in #csharp – Part 7, MVVM, is online: http://bit.ly/8cqsT1 […]

    [WORDPRESS HASHCASH] The comment’s server IP (208.74.66.43) doesn’t match the comment’s URL host IP (74.112.128.10) and so is spam.

  2. […] Windows Presentation Foundation provides us with new opportunities to build applications that are very flexible to design, easy to maintain, and clear to understand.  By taking advantage of Data Binding, Commands, and Templating, we can rethink the way we build our applications, and design them using the Model-View-ViewModel Pattern. […]



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!