I'm trying to learn about the ICommand
interface, and I'm getting a bit confused. What I want, is to have commands which don't require the object
parameter because it's never used.
class MainWindowViewModel
{
private int ZoomLevel { get; set; }
public bool CanExecute { get; set; }
public ICommand ToggleExecuteCommand { get; set; }
public ICommand IncrementZoomCommand { get; set; }
public MainWindowViewModel()
{
IncrementZoomCommand = new RelayCommand(IncrementZoom, param => CanExecute);
ToggleExecuteCommand = new RelayCommand(ChangeCanExecute);
}
public void IncrementZoom(object obj)
{
ZoomLevel++;
}
public void ChangeCanExecute(object obj)
{
CanExecute = !CanExecute;
}
}
Here is my RelayCommand class
public class RelayCommand : ICommand
{
private Action<object> execute;
private Predicate<object> canExecute;
private event EventHandler CanExecuteChangedInternal;
public RelayCommand(Action<object> execute)
: this(execute, DefaultCanExecute)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
if (canExecute == null)
{
throw new ArgumentNullException("canExecute");
}
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
this.CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
this.CanExecuteChangedInternal -= value;
}
}
public bool CanExecute(object parameter)
{
return this.canExecute != null && this.canExecute(parameter);
}
public void Execute(object parameter)
{
this.execute(parameter);
}
public void OnCanExecuteChanged()
{
EventHandler handler = this.CanExecuteChangedInternal;
if (handler != null)
{
handler.Invoke(this, EventArgs.Empty);
}
}
public void Destroy()
{
this.canExecute = _ => false;
this.execute = _ => { return; };
}
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
Due to the fact that the RelayCommand
class has been implemented using Action<Object>
(seems universal across SO) I have to pass an object into my IncrementZoom
method. It seems strange to me that the IncrementZoom
method has to have an object passed in which is never used. Would I need to create another class ParameterlessRelayCommand
which has all the object signatures removed from the constructors, methods, properties etc...