1

I have the following scenario:

public class MyCommand : ICommand
{
    MyViewModel _viewModel;

    public MyCommand(MyViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _viewModel.SomeMethod();
    }
}

Essentially, this command will simply call a method in my ViewModel when a button is clicked. CanExecute always returns true.

The issue is that even though this is generally considered to be the best way of doing things, it isn't very elegant. It begs the question of why I need a command to do this very simple process.

Why can't I just skip the command, and call the method directly?

I've had a think about this, and the only way that I can see to achieve this would be to create a command where I can specify the method name that I want to call in the CommandParameter property on my button.

I hope someone else can offer an elegant solution to this problem.

2
  • 1
    1) This isn't considered the best way of doing things 2) you can call the method directly, but you have to jump through idiot hoops in the UI to do it that are more expensive than using the ICommand pattern. Commented Jan 14, 2015 at 15:15
  • You are also splitting the logic between two parts, that is View and ViewModel, if anyone will come along and maintain this code they will have to look in 2 places rather than one, i.e. ViewModel. Commented Jan 14, 2015 at 17:05

2 Answers 2

4

You can use the "CallMethodAction" action from Blend SDK to call a method on the view model from your view. It will look something like this:

<Button ...>
  <i:Interaction.Triggers> 
    <i:EventTrigger EventName="Click"> 
      <ei:CallMethodAction MethodName="MyMethod" TargetObject="{Binding}" /> 
    </i:EventTrigger> 
  </i:Interaction.Triggers> 
</Button>

However it is still considered the best practice to use commands for that. As Ayyappan mentioned, you could use a library like MVVM Light Toolkit so you don't have to write your own implementation of ICommand.

PS: See also WPF: MVVM: Command vs CallMethodAction?

Sign up to request clarification or add additional context in comments.

Comments

2

You can use RelayCommand from MVVMLight or DelegateCommand from PRISM. They both will give a generic way of implemeting Commands. Or even you can create your own Common command class and use it. Refer the sample below.

public class ViewModel : INotifyPropertyChanged
    {
        public BaseCommand GetDataCommand { get; set; }

        public ViewModel()
        {
            GetDataCommand = new BaseCommand(GetData);            
        }

        private void GetData(object param)
        {

        }  
    }

    public class BaseCommand : ICommand
    {
        private Predicate<object> _canExecute;
        private Action<object> _method;
        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        public BaseCommand(Action<object> method, Predicate<object> canExecute=null)
        {
            _method = method;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }

            return _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _method.Invoke(parameter);
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.