Why use a RelayCommand or DelegateCommand instead of just implementing ICommand?
Asked Answered
E

2

8

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?

Emmott answered 13/9, 2011 at 13:43 Comment(2)
Just as a note. You pass a PersonVM into your command but never use it, instead you use the parameter. Maybe a typo, otherwise you should reconsider the use of the parameterErudite
Yeah, that was a typo, thanks for spotting it!Emmott
S
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.

Steersman answered 13/9, 2011 at 13:48 Comment(2)
This could be solved just by using a abstract BaseCommand and BaseVM classes, don't? (Remember that I had never done anything in the 'real world' with WPF/MVVM)Emmott
yes, of course, you can create your own, this is what we did actually, and it works. but in retrospect (and with the evolving of those frameworks - you have so many choices now), I think it's better to use something commonly used and heavily tested, to avoid the pitfalls that you'll always encounter...Steersman
E
3

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.

Erudite answered 13/9, 2011 at 13:48 Comment(1)
Yeah, you don't need another classes while using DelegateCommands, but this violates the SRP, I think it is better to have lots of small classes than few large classes...Emmott
S
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.

Steersman answered 13/9, 2011 at 13:48 Comment(2)
This could be solved just by using a abstract BaseCommand and BaseVM classes, don't? (Remember that I had never done anything in the 'real world' with WPF/MVVM)Emmott
yes, of course, you can create your own, this is what we did actually, and it works. but in retrospect (and with the evolving of those frameworks - you have so many choices now), I think it's better to use something commonly used and heavily tested, to avoid the pitfalls that you'll always encounter...Steersman

© 2022 - 2024 — McMap. All rights reserved.