Why use a RelayCommand or DelegateCommand instead

2019-02-13 08:45发布

问题:

I'm just learning about MVVM in WPF, I'm completely new both to WPF as to MVVM (I understand how it works, but have never used it...)

Every single tutorial/article I find on the web, it uses either RelayCommand, or the DelegateCommand.

In my opnion, these patterns obligues the VM to violate the SRP principle, since it will hold the command logic inside them.

Why not just use a custom implementation of the ICommand interface? Just like this:

Imagine that you're displaying a person and saving it to the DB:

My Xaml would be this:

<StackPanel>                         
    <TextBlock Width="248" Height="24" Text="The name is:: " />
    <TextBlock Width="248" Height="24" Text="{Binding Name}">            
    </TextBlock>
    <TextBox HorizontalAlignment="Left" Name="textBox1" Width="120" Height="23" 
             VerticalAlignment="Top" Text="{Binding Name}"
             />
    <Button  Name="Salvar" VerticalAlignment="Bottom" 
            Command="{Binding SavePerson}" 
            CommandParameter="{Binding}">Save</Button>
</StackPanel>

And this is my VM:

public class PersonVM: INotifyPropertyChanged
{
    private string nameValue;

    public string Name
    {
        get{
            return nameValue;
        }
        set
        {
            if (value != this.nameValue)
            {
                this.nameValue= value;
                NotifyPropertyChanged("Name");
            }
        }
    }


    public ICommand SavePerson{ get { return new SavePersonCommand(); } }
    #region INotifyPropertyChanged Members


    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    #endregion
}

And this is my Command:

public class SavePersonCommand: ICommand
{       
    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return (parameter as PersonVM) != null;            
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
            PersonVM person = parameter as PersonVM;
            if(person != null)
                //Actually Save the person...            
    }   


    #endregion
}

What's the problem with my approach?

回答1:

If you won't use some base command (of a framework or your own custom command) you'll find yourself writing the same code over and over again. For example: you don't raise CanExecuteChanged event in your own command. The same goes for implementing INotifyPropertyChanged. That's why everyone's using one or another MVVM framework.



回答2:

Nothing ... but DelegateCommand is useful if you have a really specific Command just for your ViewModel and you don't want to expose it to others because it is really just for your ViewModel. Also i like DelegateCommands because they don't need another class which you just pass in your ViewModel, it is less code to write. Your approach is useful if your supplied ViewModel is a base ViewModel which is shared alot which also allows sharing your Command.