4

I've found view models to be very useful for splitting user interface and business logic code. However, I've also made the experience that for small, simple windows a view model class just adds a lot of additional code, effectively reducing maintainability instead of improving it.

Let me give you a simple, real-world example that I've had recently: A dialog window providing two (fixed-text) buttons and a customizable text block.

  1. Using plain old x:Name-based code-behind programming technique, this is a matter of a few lines of code (set the text, handle the two button clicks by returning a value and closing the window) -- clean and simple.

  2. Doing it the "recommended way", i.e., creating a view model class (implementing INotifyPropertyChanged or inheriting DependencyObject) and defining Commands requires an awful lot of code compared to the solution above (especially since there is no concise way to define "local variable + property + raise PropertyChanged" in VB) -- making the solution less readable and more error-prone.

So, currently I'm using the pragmatic approach of choosing between "plain old x:Name" and view model on a case-by-case basis. However, the wealth of blog/forum postings claiming that the view model should be used all the time makes me wonder whether I've overlooked something.

Did I overlook something?

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Heinzi
  • 167,459
  • 57
  • 363
  • 519

5 Answers5

4

I'm all for MVVM, but the window you're describing can be implemented once and then filled as needed when you want to open one. So the ViewModel might look like this:

public SmallDialogTask
{
    string Title { get; set; }
    string Text { get; set; }
    string AcceptButtonLabel { get; set; }
    string RejectButtonLabel { get; set; }

    Command AcceptCommand { get; }
    Command RejectCommand { get; }
}

Implement this once and use inheritance to configure the various instances where you need it. As you can see from my example, this allows you to encode much more semantics into your class.

See also DRY, my question about MVVM dialogs and -- just for reference -- my blog post about MVVM.

Community
  • 1
  • 1
David Schmitt
  • 58,259
  • 26
  • 121
  • 165
  • Sounds good, although if you're stuck with VB, it's still an awful lot of code: Your SmallDialogTask code example would have more than 50 LOC, and the lack of anonymous methods would make defining the Commands a bit cumbersome (you cannot just capture a window reference in a lambda expression to set its DialogResult, etc.). I'm desperately waiting for VB10... – Heinzi Oct 13 '09 at 09:04
3

You can use data binding without defining a view model - and in most "small" windows there isn't mush logic - so you don't actually need change notification.

Just set DataContext = this and data-bind to properties of the window class.

Commands, on the other hand, don't have good simple version so I'll just use good old event handling.

(I also think that MVVM is overkill for a lot of not-so-small windows, but I'm obviously in the minority on that one)

Nir
  • 29,306
  • 10
  • 67
  • 103
1

I do the same.

Small dialogs and quick choice or information messages just get done in the simplest possible way. I try not to overcomplicate things with patterns that are unnecessary. The main application windows and anything larger is generally done with MVVM.

(So either you haven't missed anything, or I've missed the same thing.)

Simon P Stevens
  • 27,303
  • 5
  • 81
  • 107
1

I do something similar however in the situations where i just want a very small window that does something very basic i at least implement an interface and call it through a gateway so that i can call it in a testable way. Something like this :

//eg . in a viewmodel.cs or command.cs


var sometextIwantUserToEnter = UIServices.GetMeSomethingThatCan().GetText();

My window will implement IGetText and i do all the Window showing and result checking in the window itself in the GetText method. This keeps everything isolated in the window and i can assert that the service was called in my tests.

Hope that made sense.

Steve Psaltis
  • 665
  • 4
  • 8
1

You don't have to implement INotifyPropertyChanged in a view model class. You only need to do this if you need change notification, which, for simple dialogs, you don't.

I can't speak to VB-specific issues, but in C# the code that results is at least as simple and concise as it would be if it lived in the window's code-behind - and frequently more so, if you try to implement commanding behavior without implementing commands. ("I'll just set IsEnabled to true in this property setter, so that the OK button is enabled once data is entered," is one of those sentences where the word "just" turns out to be a damn lie.)

The counterargument to this - "sure, but if I don't implement change notification, then I can't do X and Y when something changes a property value" - undercuts the assertion that what you're building is simple.

I find that in general, nothing is as simple as I think it's going to be when I first start it. It's a lot easier to add change notification and commands to a view model class than it is to refactor a view model class out of a window's code-behind so that I can add change notification and commands to it.

Finally, if you use simple view model classes to back simple views in all cases but one, that one case is going bite you (or some other developer) in the ass someday. There's a lot to be said for consistency if the cost of consistency is low.

Robert Rossney
  • 94,622
  • 24
  • 146
  • 218