96

Is orthodox MVVM implementation pointless? I am creating a new application and I considered Windows Forms and WPF. I chose WPF because it's future-proof and offer lots of flexibility. There is less code and easier to make significant changes to your UI using XAML.

Since the choice for WPF is obvious, I figured that I may as well go all the way by using MVVM as my application architecture since it offers blendability, separation concerns and unit testability. Theoretically, it seems beautiful like the holy grail of UI programming. This brief adventure; however, has turned into a real headache. As expected in practice, I’m finding that I’ve traded one problem for another. I tend to be an obsessive programmer in that I want to do things the right way so that I can get the right results and possibly become a better programmer. The MVVM pattern just flunked my test on productivity and has just turned into a big yucky hack!

The clear case in point is adding support for a Modal dialog box. The correct way is to put up a dialog box and tie it to a view model. Getting this to work is difficult. In order to benefit from the MVVM pattern, you have to distribute code in several places throughout the layers of your application. You also have to use esoteric programming constructs like templates and lamba expressions. Stuff that makes you stare at the screen scratching your head. This makes maintenance and debugging a nightmare waiting to happen as I recently discovered. I had an about box working fine until I got an exception the second time I invoked it, saying that it couldn’t show the dialog box again once it is closed. I had to add an event handler for the close functionality to the dialog window, another one in the IDialogView implementation of it and finally another in the IDialogViewModel. I thought MVVM would save us from such extravagant hackery!

There are several folks out there with competing solutions to this problem and they are all hacks and don’t provide a clean, easily reusable, elegant solution. Most of the MVVM toolkits gloss over dialogs and when they do address them, they are just alert boxes that don’t require custom interfaces or view models.

I’m planning on giving up on the MVVM view pattern, at least its orthodox implementation of it. What do you think? Has it been worth the trouble for you if you had any? Am I just a incompetent programmer or does MVVM not what it's hyped up to be?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
ATL_DEV
  • 9,256
  • 11
  • 60
  • 102
  • 10
    I've always questioned whether or not MVVM is over-engineering. Interesting question. – Taylor Leese May 09 '10 at 17:23
  • 12
    Patterns like MVVM and MVC seem like overengineering, until you have to perform some modifications or change out a component. The first time you have to do that, all of the ceremony *pays for itself.* – Robert Harvey May 09 '10 at 17:34
  • If you know why you are doing it, MVC and MVVM is pretty easy and straightforward. If you made something that is hard to understand and/or clearly violates SoC or other principles, it is clearly overengineering. Summary: if you make it simple enogh, it won't be over-engineered and won't be complicated either. – Venemo May 09 '10 at 17:41
  • 42
    Lambdas are esoteric? news to me. – Ray Booysen Jun 09 '10 at 08:06
  • 6
    @Ray - Haha, +1 for that comment! :D – Venemo Jun 11 '10 at 15:10
  • 1
    @JoelRodgers: You are absolutely right, MVVM is great in theory but WPF's data binding support is still very limited for it, and you have to spent lots of time on thinking about hacks to bind your ViewModel to View. – Alex Burtsev Jan 12 '11 at 15:07
  • 8
    As Alan Cooper pointed out over a decade ago in *About Face*, if you're designing UIs and modal dialogs aren't an edge case, you're probably doing something wrong. – Robert Rossney Feb 27 '11 at 20:23
  • 2
    This question is probably better suited to programmers.stackexchange.com because that site seems to favor more discussion, while stackoverflow prefers questions that have a direct right or wrong answer. – chilltemp Apr 29 '11 at 21:32
  • 1
    @chilltemp: This is a really old question, I think only mod intervention would get this anywhere. – BoltClock May 03 '11 at 20:40

8 Answers8

62

Sorry if my answer became a little lenghty, but don't blame me! Your question is lengthy as well.

In summary, MVVM is not pointless.

The clear case in point is adding support for a Modal dialog box. The correct way is to put up a dialog box and tie it to a view model. Getting this to work is difficult.

Yes, it truly is.
However, MVVM provides you a way for separating the UI's appearance from its logics. Noone forces you to use it everywhere, and noone is holding a gun against your forehead to make you create a separate ViewModel for everything.

Here is my solution for this particular example:
How the UI handles a certain input is none of the ViewModel's business. I would add code to the View's .xaml.cs file, which instantiates the dialog box and sets the same ViewModel instance (or something else, if needed) as its DataContext.

In order to benefit from the MVVM pattern, you have to distribute code in several places throughout the layers of your application. You also have to use esoteric programming constructs like templates and lamba expressions.

Well, you don't have to use it in several places. This is how I would solve it:

  • Add the XAML to the View, and nothing in the .xaml.cs
  • Write every app logic (except the stuff that would directly operate with UI elements) inside a ViewModel
  • All the code that should be done by the UI but has nothing to do with business logic goes into the .xaml.cs files

I think that the purpose of MVVM is primarily to separate the logic of the application and the concrete UI, therefore enabling easy modifications (or complete replacement) of the UI.
I use the following principle: the View can know and assume anything it wants from the ViewModel, but the ViewModel can know NOTHING about the View.
WPF provides a nice binding model which you can use to achieve exactly that.

(BTW, templates and lambda expressions aren't esoteric if used right. But if you don't want to, don't use them.)

Stuff that makes you stare at the screen scratching your head.

Yeah, I know the feeling. Exactly what I was feeling when I first saw MVVM. But once you get the hang of it, it won't feel bad anymore.

I had an about box working fine ...

Why would you put a ViewModel behind an about box? No point in that.

Most of the MVVM toolkits gloss over dialogs and when they do address them, they are just alert boxes that don’t require custom interfaces or view models.

Yes, because the very fact that a UI element is in the same window, or another window, or is orbitting Mars at the moment is none of the ViewModels' concern.
Separation of Concerns

EDIT:

Here's a very nice video the title of which is Build your own MVVM framework. It's worth watching.

Venemo
  • 18,515
  • 13
  • 84
  • 125
  • 3
    +1 for the last three words. But the rest of the answer is good, too. :) – Robert Harvey May 09 '10 at 17:29
  • 13
    +1 for the advice about using code-behind. It's a common misconception that it's "bad" to use code-behind in MVVM... but for purely UI-related stuff, that's the way to go. – Thomas Levesque May 09 '10 at 18:06
  • 1
    @Thomas: Yeah, I couldn't agree more. I've seen several implementations where people put all the code (even UI-related) into the ViewModel, because (according to them) "that is where the code is". It was quite hacky. – Venemo May 09 '10 at 19:20
  • 4
    @Venemo, I do think you can encapsulate a lot of the stuff you'd want to put in the code-behind using techniques like custom Behaviors, which is handy if you find yourself repeatedly writing glue code. In general though, I do think it's better to use code-behind for glue than to hack together awkward XAML. The main concern, in my mind, is making sure there's nothing in the code-behind sophisticated enough to warrant unit testing. Anything sufficiently complex is better off encapsulated in the ViewModel or an extension class, like a Behavior or MarkupExtension. – Dan Bryant May 09 '10 at 20:03
  • 1
    @Dan, yes, my point exactly. What you say is equal to what SoC is saying. – Venemo May 09 '10 at 21:08
  • 1
    @Venemo "Why would you put a ViewModel behind an about box? No point in that." We have 2 applications that share the same about box. So, we inject the correct ViewModel for the given application. Good or bad - who knows but that's how we do it. – ihatemash Nov 08 '10 at 20:35
  • 8
    @ Thomas: You are right, the biggest myth about MVVM is that the purpose of MVVM is to get rid of code-behind. The purpose is to get the Non-UI ocde out of the code behind. Putting UI-only code in the ViewModel is just as bad as putting problem domain code in the code-behind. – Jim Reineri Aug 24 '11 at 16:56
8

Getting this to work is difficult. In order to benefit from the MVVM pattern, you have to distribute code in several places throughout the layers of your application. You also have to use esoteric programming constructs like templates and lamba expressions.

For a commonplace modal dialog box? You are certainly doing something wrong there - MVVM implementation doesn't have to be that complex.

Considering you are new to both MVVM and WPF, it is likely you are using suboptimal solutions everywhere and unnecessarily complicate things - at least I did so when I first went WPF. Make sure that the problem is really MVVM and not your implementation before giving up.

MVVM, MVC, Document-View, etc. is an old family of patterns.. There are drawbacks, but no fatal flaws of the kind you describe.

ima
  • 8,105
  • 3
  • 20
  • 19
6

I am in the middle of a quite complex MVVM development using PRISM so I already had to cope with this kind of concerns.

My personal conclusions:

MVVM vs MVC /PopUps & co

  • MVVM is really a great pattern and in most cases it completely replaces MVC thanks to the powerful data binding in WPF
  • Calling your service layer directly from the presenter is a legitimate implementation in most cases
  • Even quite complex List /Detail scenarios may be implemented by pure MVVM thanks to the {Binding Path=/} syntax
  • Nonetheless, when complex coordination between multiple views needs to be implemented, a controller in mandatory
  • Events may be used; the old pattern which implies storing IView (or AbstractObserver) instances in the controller is obsolete
  • The controller can be injected in each Presenter by IOC container
  • Prism’s IEventAggregator service is another possible solution if the only use of the controller is event dispatching (in this case it can completely replace the controller)
  • If views are to be dynamically created, this is a very well suited job for the controller (in prism the controller will get injected (IOC) a IRegionManager )
  • Modal dialog boxes are mostly obsolete in modern composite applications, except for really blocking operations like mandatory confirmations; in these cases modal activation can be abstracted as a service called inside the controller, and implemented by a specialized class, which also allows for advanced presentation-level unit testing. The controller will, for example, call IConfirmationService.RequestConfirmation(“are you sure”) which will trigger a modal dialog display at runtime and can be easily mocked during unit testing
dan ionescu
  • 61
  • 1
  • 1
5

I deal with the dialogs issue by cheating. My MainWindow implements an IWindowServices interface that exposes all of the application-specific dialogs. My other ViewModels can then import the services interface (I use MEF, but you could easily just pass the interface through constructors manually) and use it to accomplish what is necessary. For instance, here is what the interface looks like for a little utility application of mine:

//Wrapper interface for dialog functionality to allow for mocking during tests
public interface IWindowServices
{
    bool ExecuteNewProject(NewProjectViewModel model);

    bool ExecuteImportSymbols(ImportSymbolsViewModel model);

    bool ExecuteOpenDialog(OpenFileDialog dialog);

    bool ExecuteSaveDialog(SaveFileDialog dialog);

    bool ExecuteWarningConfirmation(string text, string caption);

    void ExitApplication();
}

This puts all of the Dialog executions in one place and it can be easily stubbed out for unit testing. I follow the pattern that the client of the dialog has to create the appropriate ViewModel, which they can then configure as needed. The Execute call blocks and afterward the client can look at the contents of the ViewModel to see the Dialog results.

A more 'pure' MVVM design may be important for a large application, where you need cleaner insulation and more complex composition, but for small to medium sized apps, I think a practical approach, with appropriate services to expose required hooks, is quite sufficient.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Dan Bryant
  • 27,329
  • 4
  • 56
  • 102
  • But where do you call it? Wouldn't it be better to just construct the dialog within the IWindowServices class's functions rather than have it passed in. That way the calling model view wouldn't have to know anything about the particular dialog implementation. – ATL_DEV May 13 '10 at 16:48
  • The interface is injected into whichever of my ViewModel instances needs access to the application dialogs. In most cases, I'm passing in the ViewModel for the dialog, but I did get a bit lazy and use the WPF OpenFileDialog and SaveFileDialog for the file dialog calls. My primary goal was isolation for the purposes of unit testing, so this is sufficient for that goal. If you wanted better isolation, you would probably want to create an OpenFileViewModel and SaveFileViewModel, which would duplicate the necessary properties for the dialogs. – Dan Bryant May 13 '10 at 17:02
  • Note that this is definitely not a pure approach, in that the ViewModel that's using the dialogs knows about the specific ViewModel for each dialog it wants to open. I feel that this is fairly clean, but you could always add an additional layer of insulation with a class that purely exposes the parameters required for dialog usage, hiding any unnecessary visibility of ViewModel properties used during binding. For smaller applications, I feel this additional insulation is overkill. – Dan Bryant May 13 '10 at 17:04
5

Design patterns are there to help you, not hinder. A small part of being a good developer is knowing when to "break the rules". If MVVM is cumbersome for a task and you have determined the future value isn't worth the effort, then don't use the pattern. For example, as other posters have commented, why would you go through all the overhead to implement a simple about box?

Design patterns were never intended to be dogmatically followed.

RMart
  • 548
  • 1
  • 5
  • 20
  • 2
    Correct. A simple about box should be simple, but what if you have to display information such as version, licensing, running process, company name, etc. This is all information that lives somewhere. In standard forms, you can just bind all that information and be done with it. MVVM says you should create a view model for it, which is redundant. – ATL_DEV Aug 05 '11 at 17:25
2

As the pattern itself MVVM is great. But WPF's control library shipped with NET 4.0 data binding support is very limited, it is a lot better than WinForm, but still it's not enough for bindable MVVM, I would say it's power is about 30% of what is needed for bindable MVVM.
Bindable MVVM : it's UI where ViewModel is wired with View only using data binding.
MVVM pattern is about the object representation of the ViewState, it doesn't describe how you maintain the sync between View and ViewModel, in WPF it's data binding but it can be anything. And actually you can use MVVM pattern in any UI toolkit which support's events\callbacks, you can use it in pure WinAPI in WinForms (I did, and it's not much more work with events\callbacks), and you can even use it in Text Console, like rewrite DoS's Norton Commander using MVVM pattern.

In short: MVVM is not pointless, it's great. NET 4.0 WPF's control library is trash.

Here is the simple proof of concept ViewModel which you can't data bind in pure MVVM manner using WPF.

public class PersonsViewModel
{
    public IList<Person> PersonList;
    public IList<ColumnDescription> TableColumns;
    public IList<Person> SelectedPersons;
    public Person ActivePerson;
    public ColumnDescription SortedColumn;
}

You can't data bind WPF's DataGrid column headers, you can't data bind selected rows, etc etc, you will either do it in code simple way, or write a 200 lines of XAML hack code for these 5 lines of simplest ViewModel. You can only imagine how things get worser with complex ViewModels.
So the answer is simmple unless you are writing Hello World application, using bindable MVVM in WPF is pointless. You will spent most of your time thinking on hack to bind you ViewModel. Data binding is nice but be ready to fallback to event's 70% of time.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Alex Burtsev
  • 12,418
  • 8
  • 60
  • 87
  • You could bind this, with converters, to a DataGrid. – Cameron MacFarland Feb 27 '11 at 15:07
  • @CameronMacFarland: Not all, some properties are readonly and unbindable, some simply doesn't exist and there are only event's that report state change. – Alex Burtsev Feb 27 '11 at 15:10
  • I'll admit I don't have much experience using the WPF DataGrid. I tend to avoid it as it's ugly and doesn't fit with WPF anymore. Having said that a combination of converters and AttachedProperties to handle events should get you what you need. – Cameron MacFarland Feb 27 '11 at 15:50
  • @CameronMacFarland: I agree with you that it's ugly, moreover i would say that all WPF controls library is ugly. And yes combination of converters and attached properties will do the job. But the code to write for this will be much larger and uglier than standard event handlers. – Alex Burtsev Feb 27 '11 at 15:54
  • 1
    Alex, the problems you're having are with the design of the DataGrid, not with MVVM. It's simply incorrect to say that "Data binding is nice but be ready to fallback to event's 70% of time." I have written some objectively huge WPF applications in which there are no event handlers in the UI whatsoever - with the exception of the event handler that the (Telerik) data grid needs for initialization. – Robert Rossney Feb 27 '11 at 20:17
  • @Robert, I wrote it wrong, I should rather say WPF control library shipped with NET 4.0 is complete trash. – Alex Burtsev Feb 27 '11 at 20:26
  • 3
    I think that you might have more success if instead of adopting the attitude, "This is badly designed and doesn't work," you tried, "Why is this working for other people but not for me?" You might find that the reason things are hard to do is that you don't know how to do them yet. – Robert Rossney Feb 27 '11 at 20:59
  • @Robert: I'm sure you are right at some percent, I'm really new to WPF, and don't know to do many things. And your question is absolutely correct, even more it's the question of the day for me: "Why is this working for other people but not for me?" But I come to another conclusion than you. This "other" people simply doesn't develop real life application's, and they have little programming practice they are theoretics. I doubt that lot's of this people know for example that WPF's TextBox.SelectedText property is not Dependency property and you can't bind to it, they have never stumbled on this – Alex Burtsev Feb 27 '11 at 21:13
0

I have seen the same issue with a lot MVVM implementations when it comes to (modal) dialogs. When I look at the participants of the MVVM Pattern then I have the feeling that something is missing to build a coherent application.

  • View contains the specific GUI controls and defines the appearance of the user interface.
  • ViewModel represents the state and behavior of the presentation.
  • Model can be a business object from the domain layer or a service which provides the necessary data.

But missing is:

  • Who creates the ViewModels?
  • Who is responsible for the application workflow?
  • Who mediates between ViewModels when they need to communicate with each other?

My approach is to introduce a (Use-Case) Controller which is responsible for the missing points. How this works can be seen at the WPF Application Framework (WAF) sample applications.

jbe
  • 6,976
  • 1
  • 43
  • 34
  • The Mediator pattern as implemented by Josh Smith solved all my View Model communication issues. Messenger.NotifyColleagues provided a way to have completely independent view models that knew how to respond to global events (if they cared) without having any two view models know about each other. It's saved our bacon a few times already now. – JasonD May 09 '10 at 18:43
0

No, it’s not pointless, but it is difficult to wrap your head around even though the pattern itself is ridiculously simple. There are tons of misinformation out there and various groups who battle over the proper way. I think with WPF and Silverlight you should use MVVM or you’ll be over coding and attempting to solve problems in a new model the “old” win forms methodology which just leads you into trouble. This is more the case in Silverlight since everything is required to be asynchronous (hacks around this are possible, but you should just pick another platform).

I’d suggest reading this article Simplifying the WPF TreeView by Using the ViewModel Pattern carefully to see how MVVM can be implemented well and allow you to change your win forms mentality to the new way of thinking in MVVM. In short when you want to get something done apply the logic to the ViewModel first not the View. You want to select an item? Change an icon? Don’t iterate over UI elements, just update the models properties and let data-binding do the nitty gritty.

TugboatCaptain
  • 4,150
  • 3
  • 47
  • 79