Answer
ICommand exposes Execute, CanExecute, and CanExecuteChanged. Controls like Button bind their Command property to a view-model command, keeping logic out of code-behind. CanExecute enables/disables the control automatically. Command and RelayCommand implementations wrap methods and optional predicates.
[RelayCommand(CanExecute = nameof(CanSave))]
async Task SaveAsync() => await _repo.SaveAsync(Item);
bool CanSave() => !string.IsNullOrEmpty(Item.Name);Real-world example A Save button auto-disables until the form is valid because its bound command's CanExecute returns false for empty input.