Question

We have a large-ish app with a ribbon. The ribbon buttons are all bound to commands in my main view model (the data context of the main app window).

The constructor for MainViewModel is starting to grow as we create lots of RelayCommands (bound to the various ribbon commands). It looks something like this:

    public MainWindowViewModel()
    {
        this.OpenProjectCommand = new RelayCommand(() =>
            {
                 // buncha code
            });

        this.ProjectTypesCommand = new RelayCommand(() =>
            {
                // more code
            });

        this.NewSectionCommand = new RelayCommand(() =>
            {
                // code code code...
            });
        // ... only three ribbon buttons down, this is gonna get huge...
    }

I'd prefer to have separate classes implementing each of the commands, rather than tons of inline code in MainViewModel's constructor. (Or creating lots of delegates in the MainViewModel, e.g. OpenProject, CanOpenProject, and then passing in references to them to the RelayCommand constructors).

Why don't I simply implement ICommand in a CommandBase and then create separate commands? Because I want to be "standard friendly" as per this question.

Is there a standard ICommand implementation I can use so that my commands are in separate classes?

I'd prefer not to add more MVVM frameworks into the mix since I'm already using MVVM Light. But I also don't want to reinvent the wheel.

Update: MainViewModel.cs doesn't need to be cluttered with scores of #regions or command methods. Extension methods aren't a good fit either IMHO.

Was it helpful?

Solution

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?

Cheers Laurent

OTHER TIPS

You could at least create them in the getter. You can use the ?? operator.

http://msdn.microsoft.com/en-us/library/ms173224.aspx

This basically says: Return _testCommand, but create it first if it's still null.

This way, the command is not created until it's needed!

public class TestViewModel : ViewModelBase
{
    #region OpenCommand
    private RelayCommand _testCommand;
    public RelayCommand TestCommand {
        get {
            return _testCommand = _testCommand 
                ?? new RelayCommand(
                    this.ExecuteOpenCommand, 
                    this.CanOpenCommandExecute);
        }
    }
    private void ExecuteOpenCommand()
    {
        // do stuff
    }

    private bool CanOpenCommandExecute()
    {
        return true;
    }
    #endregion
}

If your goal is to organize, you can use #region and #endregion. And like we said, if your goal is to shrink the constructing process, use the ?? operator in getters. If you just hate inline code, create private methods in combination with RelayCommand, in getters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top