0

I have a question, i watched a lot of tutorial about MVVM but i'm still confused. I have an interface with more than one button on it, i have to implement the ICommand interface for bind the command to the View.

I did it like this:

MainSolution

Main Solution
    Model
        SomeClass.cs
    ViewModel
        Commands
            SomeCommands.cs
        SomeViewModel.cs

Ok, now in the interface i have more than one button, each one do separate things, example, one is for start a thread the other one for cancel it and a third one for another thing. Should i create a separate class, that implement ICommand interface, for each button that i have on the View?

Main Solution
    Model
        SomeClass.cs
    ViewModel
        Commands
            StartCommands.cs
            CancelCommands.cs
            OtherCommands.cs
        SomeViewModel.cs

I'm asking this because when i implement the ICommand interface i have only one "Execute" method, and only one "CanExecute" method. What is the common way to implement multiple button on a View through binding?

I searched for example online without any luck... A lot of them are so confusing, and surely not for a newbie like me.

The other thing is when i have multiple View and Multiple ViewModel, should i create multiple Commands Folder for nesting it?

Main Solution
    Model
        SomeClass.cs
    ViewModel
        FirstCommands
            StartCommands.cs
            CancelCommands.cs
            OtherCommands.cs
        SecondCommands
            StartCommands.cs
            CancelCommands.cs
            OtherCommands.cs
        FirstViewModel.cs
        SecondViewModel.cs
exSnake
  • 682
  • 1
  • 8
  • 26

2 Answers2

2

IMHO having a separate class for each command in a classic MVVM approach is an overkill. Use something like the MVVMLight's RelayCommand (and the generic one if you want to pass a parameter).

Then you can define your commands as your ViewModel members and provide Execute/CanExecute implementation as part of your ViewModel as well:

public RelayCommand MyCommand { get; }

public MyView()
{
    //[...]
    this.MyCommand = new RelayCommand(this.ExecuteMyCommand, this.CanExecuteMyCommand);
}

public void ExecuteMyCommand()
{
   //do work!
}

public bool CanExecuteMyCommand()
{
   //optional - control if command can be executed at a given time
}

And you can bind to MyCommand in XAML (assuming your View is bound to your ViewModel):

<Button Content='WORK!' Command='{Binding MyCommand}' />
decPL
  • 5,384
  • 1
  • 26
  • 36
  • Why the RelayCommand accept a "Type" too? (RelayCommand), what you can do with that? A type of what? – exSnake Oct 11 '16 at 19:35
  • Parameter. Refer to http://stackoverflow.com/questions/32064308/how-to-pass-command-parameter-to-method-in-viewmodel-in-wpf – decPL Oct 11 '16 at 19:40
1

What you want is a DelegateCommand class. You can use Prism, or just google around and steal one; here's one on StackOverflow that I haven't tested but it looks legit. If you don't need a parameter for a command, just ignore the parameter argument.

A DelegateCommand implements ICommand, and calls an Action or Action<object> that you pass to its constructor, like so (from the StackOverflow answer linked above):

public DelegateCommand AddFolderCommand { get; protected set; }
public MyViewModel(ExplorerViewModel explorer)
{           
    AddFolderCommand = new DelegateCommand(ExecuteAddFolderCommand, (x) => true);
}

public void ExecuteAddFolderCommand(object param)
{          
    MessageBox.Show("this will be executed on button click later");
}

This should have been included in WPF, but wasn't, for whatever reason.

Community
  • 1
  • 1