The concept is that you bind a command to a button, and the command controls two properties of this button: "on click" and "enabled", as a result of which you laid out the interface.
The main reason you want to execute a command is to bind buttons to actions in your view model.
If you create one custom command that takes action as a constructor parameter, you can connect methods from your view model directly to your team.
public class RelayCommand: ICommandd { Action action; Func<bool> canExecute; public RelayCommand(Action action) : this(action, () => true) {} public RelayCommand(Action action, Func<bool> canExecute) { this.action = action; this.canExecute = canExecute; } public bool CanExecute(object parameter) { return canExecute(); } public void Execute(object parameter) { action(); } }
Use in your view model would be
public RelayCommand SaveCommand { get; set; } SaveCommand = new RelayCommand(OnSave); public void Save() {
If you want to connect CanExecute, you can also use the second ctor and provide the CanSave method.
public RelayCommand SaveCommand { get; set; } SaveCommand = new RelayCommand(OnSave, CanSave); public void Save() {
As you may have noticed, I reset the command parameter in my implementation. This will be sufficient in most cases and will save additional parameters in the handler methods. For the 10% remaining, I implemented RelayCommand<T> , which takes an action instead of Action and changes the Execute method to
public void Execute(object parameter) { action((T)parameter); }
which requires a parameterized handler
SaveCommand = new RelayCommand<SomeType>(OnSave); public void Save(SomeType toSave) {
This saves you from all the casting problems you encounter when using object variables, and keeps your view type models safe.