Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / WPF

WPF: If Carlsberg did MVVM Frameworks Part 1 of n

Rate me:
Please Sign up or sign in to vote.
4.76/5 (83 votes)
23 Dec 2009CPOL9 min read 274.6K   280   75
It would probably be like Cinch a MVVM framework for WPF

Contents

Introduction

It has been a while since I have undertaken a large article, so I thought it was about time I corrected that, and wrote a fairly meaty article. This article and the subsequent series of articles represents this meat. This article represents the 1st in a saga of articles that I will be unleashing on how to do a good job of MVVM when working with WPF.

For those that do not know what on earth MVVM is, it is basically a UI design pattern that is particularly suited to working with WPF thanks to the binding options available with WPF. The idea is that the ViewModel is an abstraction of the View and you should be practically able to test the entire UI by running Unit tests against the ViewModels within the system. In fact I heard one very influential Microsoft employee once said that before they saw the UI they would like to see the unit tests to see how it all worked. If you can read the unit tests and understand how the UI works, you are doing MVVM right.

Here are some nice MVVM links in case you need them:

In my opinion MVVM is a superb pattern, but there are limitations that it just does not do that well, for example how does one show a MessageBox (a modal dialog) from what is essentially a non UI class. Having worked out how to show a MessageBox from a ViewModel, how can we ensure that the code that relies on a "Yes" or "No" being picked for the ViewModel to traverse a certain code path is fully tested in the Unit tests applied to the ViewModel. This sort of thing is non trivial. I have literally seen 100s of articles stating they are good MVVM examples, you know what, they are not. They showcase basic binding without a single thought about the sort of thing I just mentioned. There are probably 100 people on the planet doing MVVM correctly, and I know a fair few of them. It is not easy until the information gets blasted into your skull by getting it wrong enough. I now feel I have got it wrong often enough to speak with some authority on how, not only how not to do it, but also how to do it right. Experience by initiation of fire and all that.

I have personally been doing WPF/MVVM for a while now and have struggled with this supposedly great pattern for pretty much most of that time, and it is only now that I feel ah yes I get how to do that 100% right. This article and subsequent articles will now share that knowledge with you. Should you want that knowledge. I leave that up to you.

So what is this article and subsequent articles all about then. Well simply put it is a MVVM framework which I am called "Cinch", and a demo app and a bunch of unit tests, which granted doesn't sound that great, but what I am hoping is as we move through the series you will actually go, aha that is kinda nice/great whatever, and that addresses exactly the trouble we had and I see how we can fix that now. Even if you do not end up using Cinch, you may find that some of its code may help you in your own work. That's cool too.

One really great thing is that the entire demo apps code behind, consists of 1 line of code, which means I can test everything from unit tests, yes everything, threads, navigation, messages between Views/ViewModels, saving files, loading files the lot. That 1 line of code ain't bad when you consider there are 4 Views and a popup all interacting together.

I hope you will see the benefit of Cinch in all of this, and the subsequent articles content.

That's the plan anyway.

Special Thanks

Before I start, I would specifically like to say a massive thanks to the following people, without whom this article and the subsequent series of articles would never have been possible. Basically what I have done with Cinch is studied most of these guys, seen what's hot, what's not, and come up with Cinch which I hope addresses some new ground not covered in other frameworks.

Mark Smith (Julmar Technology), for his excellent MVVM Helper Library, which has helped me enormously. Mark I know I asked your permission to use some of your code, which you most kindly gave, but I just wanted to say a massive thanks for your cool ideas, some of which I genuinely had not thought of. I take my hat off to you mate.

Josh Smith / Marlon Grech (as an atomic pair) for their excellent Mediator Implementation. You boys rock, always a pleasure.

Karl Shifflett / Jaime Rodriguez (Microsoft boys) for their excellent MVVM Lob tour, which I attended, well done lads.

Bill Kempf, for just being Bill and being a crazy wizard like programmer, who also has a great MVVM framework called Onyx, which I wrote an article about some time ago. Bill always has the answers, to tough questions, cheers Bill.

ALL of the WPF Disciples, for being the best online group to belong to IMHO.

Thanks guys/girl, you know who you are.

This Article Is A Bit Of A Strange One!

In a lot of ways, this article is an absolute crock of sh*t, as there will be no code and no explanations of anything in this article, but it will serve as a kind of road map of what is coming up in the series of articles... And that is about all this article really does, but I just felt it was needed to explain the other articles, somehow.

I have really struggled with how best to present this content, as there is a lot (a real lot) to get through, but finally I arrived at this decision, release a primer article that has full source code for all those that feel they can navigate the road themselves, with no explanation. The primer article (this one) will simply be used as a stepping stone on to the real meat, AKA the next articles.

This way if anyone wants to look at the code they can, all that I ask is that if people dive into the code, now, could they maybe keep complicated questions until later on in the series, as I will be going through EVERYTHING in future articles in this series. So you will get all the knowledge/content just not in this article, not yet. I will be trying my best to get the content out there quickly. I should be able to get another one up by next weekend I hope.

Prerequisites

The demo app makes use of:

  • VS2008 SP1
  • .NET 3.5 SP1
  • SQL server (see the README.txt in the MVVM.DataAccess project to learn what you have to setup for the demo app database)

What Will Be Covered In This Article?

Not much actually, what I can say is what Cinch does, and that is the following:

  • Allows view to communicate LifeCycle events to a ViewModel without any hard reference links being maintained, and no IView interface requirements. There is no link at all between the View and the ViewModel.
  • Has several attached behaviours for common tasks such as:
    • Numeric text entry
    • Run an ICommand in a ViewModel based on a RoutedEvent from an XAML FrameworkElement
    • Have a group of such ICommand/RoutedEvent Events for a single XAML FrameworkElement
  • Allows the ViewModel to determine if a Models data should be editable, the UI simply updates via bindings, based on the ViewModel driven editability state. This is available at individual Model field level, so it's very flexible.
  • Delegate validation rules which allows validation rules to be as granular as necessary
  • Native IDataErrorInfo support using the Delegate rules approach
  • IEditableObject usage to store/restore object state on edit / cancel edit
  • Weak event creation, to allow the creation of WeakEvents
  • Weak event subscription, which also allows auto unsubscriptions
  • Mediator messaging with WeakReference support out of the box
  • DI/IOC using Unity DI Container, to allow alternative Test/actual app service implementations
  • Service implementations which include (where Cinch has defaults for WPF/UnitTest for most of these, with the exception of the Popup window service which will be covered in a subsequent article and shall still be available within the attached demo code at any rate)
    • Advanced logging using Log4Net 
    • MessageBox service (which can be 100% emulated within unit tests, as if the user actually clicked a MessageBox button), thus enabling the ViewModel code to be traversed down the correct path
    • Open file service (which can be 100% emulated within unit tests, as if the user actually chose a file to open in the model OpenFileDialog), thus enabling the ViewModel code to be traversed down the correct path
    • Save file service (which can be 100% emulated within unit tests, as if the user actually chose a file to save in the model SaveFileDialog), thus enabling the ViewModel code to be traversed down the correct path
    • Popup window service, to control the showing/hiding and setup of Popup Window in WPF (which is a nightmare)
  • Threading helpers
    • Dispatcher extension methods to allow quick marshalling of a Action<T> to the correct UI Dispatcher
    • Application.DoEvents
    • Application.DoEvents (for a certain Dispatcher Priority)
    • BackgroundTaskManager with callback to alert waiting Unit tests of completion, to allow test to complete or timeout
    • ObservableCollection, which notifies CollectionChanged on correct Dispatcher thread
    • ObservableCollection, which allows a range of items to be added
  • MenuItem ICommand ViewModel implementation made easy
  • Closeable ViewModels (when working in Tabbed UI environment, which is what one should really be doing with MVVM)

What's Coming Up?

In the subsequent articles, I will be showcasing it roughly like this:

  1. A walkthrough of Cinch, and its internals - Part I
  2. A walkthrough of Cinch, and its internals - Part II
  3. How to develop ViewModels using Cinch
  4. How to Unit test ViewModels using Cinch app, including how to test Background work threads which may run within Cinch ViewModels
  5. A Demo app using Cinch

That is actually all I wanted to say right now, but I can promise you the subsequent articles WILL have a LOT of meat and examples about how to get started with Cinch.

Till then I guess, if you want you can try out/explore that attached code. If you have a specific query, could you maybe wait till all 4 parts are available and then if I have not covered what you wanted to ask, feel free to ask me.

Thanks.

As always, votes / comments are welcome.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
QuestionOne file menu command, multiple ViewModels Pin
Claire Streb14-Aug-12 11:58
Claire Streb14-Aug-12 11:58 
Hi,

I've been reading your articles and code for awhile now, and it is unclear to me how multiple ViewModels service the same command. For example, when the user selects File > Exit, I do not see how MainWindowViewModel.ExecuteExitApplicationCommand() ensures that any ViewModels are notified that the exit is occurring.

Let me provide a scenario/use case for clarification:

1) The user opens a document panel (tab1), and starts editing a record (Example: Course).
2) The user opens another document panel (tab2), and starts editing a different record (Example: Student).
3) The user selects Save All from file menu command.

What is your best solution utilizing this (or any other) approach for both ViewModels to receive the Save menu command?
Claire Streb
http://clairenstreb.brinkster.net

AnswerRe: One file menu command, multiple ViewModels Pin
Sacha Barber14-Aug-12 19:54
Sacha Barber14-Aug-12 19:54 
GeneralRe: One file menu command, multiple ViewModels Pin
Claire Streb15-Aug-12 3:33
Claire Streb15-Aug-12 3:33 
SuggestionAll MVVM stuff at one place... Pin
Cracked-Down7-Jun-12 22:11
Cracked-Down7-Jun-12 22:11 
GeneralRe: All MVVM stuff at one place... Pin
Sacha Barber7-Jun-12 23:16
Sacha Barber7-Jun-12 23:16 
GeneralMy vote of 1 Pin
VickyC#19-Feb-11 18:19
VickyC#19-Feb-11 18:19 
GeneralBinding for COMBOBOX Pin
demariano14-Sep-10 16:53
demariano14-Sep-10 16:53 
GeneralRe: Binding for COMBOBOX Pin
Sacha Barber14-Sep-10 19:56
Sacha Barber14-Sep-10 19:56 
GeneralMy vote of 5 Pin
dsdevoy9-Aug-10 11:14
dsdevoy9-Aug-10 11:14 
Questionlog4net.dll Pin
Leung Yat Chun15-Jul-10 1:04
Leung Yat Chun15-Jul-10 1:04 
AnswerRe: log4net.dll Pin
Sacha Barber15-Jul-10 1:25
Sacha Barber15-Jul-10 1:25 
QuestionLinq To MySQL or other DBs? Pin
Krischu23-Feb-10 23:31
Krischu23-Feb-10 23:31 
AnswerRe: Linq To MySQL or other DBs? Pin
Fredrik Bornander24-Feb-10 0:21
professionalFredrik Bornander24-Feb-10 0:21 
GeneralRe: Linq To MySQL or other DBs? Pin
Krischu5-Mar-10 0:10
Krischu5-Mar-10 0:10 
GeneralRe: Linq To MySQL or other DBs? Pin
Sacha Barber5-Mar-10 0:30
Sacha Barber5-Mar-10 0:30 
GeneralCinch and XBAP Pin
Maria Klimkovich15-Feb-10 6:54
Maria Klimkovich15-Feb-10 6:54 
GeneralRe: Cinch and XBAP Pin
Sacha Barber15-Feb-10 20:06
Sacha Barber15-Feb-10 20:06 
GeneralRe: Cinch and XBAP Pin
Sacha Barber15-Feb-10 20:07
Sacha Barber15-Feb-10 20:07 
GeneralSome points. Pin
Rodrigo Rodriguez27-Dec-09 5:10
Rodrigo Rodriguez27-Dec-09 5:10 
GeneralRe: Some points. Pin
Sacha Barber27-Dec-09 20:56
Sacha Barber27-Dec-09 20:56 
GeneralCommandSucceeded Issue Pin
masontwo17-Dec-09 7:08
masontwo17-Dec-09 7:08 
GeneralRe: CommandSucceeded Issue Pin
Sacha Barber17-Dec-09 22:46
Sacha Barber17-Dec-09 22:46 
GeneralRe: CommandSucceeded Issue Pin
Sacha Barber19-Jan-10 5:39
Sacha Barber19-Jan-10 5:39 
GeneralMy vote of 2 Pin
Allen Anderson8-Nov-09 9:49
Allen Anderson8-Nov-09 9:49 
GeneralRe: My vote of 2 Pin
Sacha Barber5-Dec-09 0:35
Sacha Barber5-Dec-09 0:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.