This project has moved. For the latest updates, please go here.

How to separate commands into separate classes for a large viewmodel?

Mar 4, 2014 at 4:33 PM
Edited Mar 4, 2014 at 4:38 PM
Hi Laurent,

Having fun learning and using the MVVM Light toolkit for a large ribbon-driven app. I've run into a headache, though: Our main viewmodel will have many commands, bound to our various ribbon buttons. I'd prefer to have each command in its own class so that MainViewModel.cs doesn't grow to thousands of lines of command logic.

I asked a question on SO but no luck so far. Is there a "subclass-friendly" version of RelayCommand that lets one modularize command methods into classes? If not, why not and what would you advise?

Mar 4, 2014 at 7:48 PM

The way I do is that I have "sub-viewmodels". For example, in the case of the MainViewModel, let's imagine that you have a PrintCommand and a CancelPrintCommand. You can have a new class called "PrinterViewModel", and expose an instance of this class in the MainViewModel. Have the PrintCommand and the CancelPrintCommand in this PrinterViewModel (this also allows modular unit testing, which is neat).

Then in XAML:

Command="{Binding Main.Printer.PrintCommand}"

Alternatively, you could do

new RelayCommand(() => Printer.DoSomething())

Does that make sense?

Mar 4, 2014 at 7:55 PM
Edited Mar 4, 2014 at 7:55 PM
Thanks, I was thinking about going it that way. We host an editor control with a bunch of formatting commands, for instance, so I'll create a separate viewmodel for the "active editor".

Out of curiosity, is there a reason MVVM Light uses RelayCommand rather than a subclassable ICommand? I mean, that lambda syntax is super-convenient, but why no CommandBase for "heavier" commands? Is it just that it's never been needed (using modular viewmodels) or is there some technical reason?
Mar 4, 2014 at 8:19 PM
I think the last time I implemented ICommand (or worked on a project that implemented ICommand) was probably 3 or 4 years ago. It's just that it is a hassle to have to implement a whole class every time. I prefer to have multiple viewmodels with each a set of RelayCommands, than one viewmodel with a set of commands that each implement ICommand separately. In my experience it's more efficient this way.

That said, ICommand is there if you use MVVM Light or not, and you can absolutely implement that if you prefer :)

Mar 4, 2014 at 11:55 PM
That makes sense, Laurent--thanks for clarifying!