Reputation: 9723
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.
Upvotes: 1
Views: 1213
Reputation: 20756
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?
Upvotes: 4
Reputation: 5366
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);
}
}
Upvotes: 2