100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET

The RelayCommand Pattern

A reusable ICommand implementation that wraps Execute and CanExecute delegates, eliminating the need to write a bespoke command class for every ViewModel action.

CommandsBeginner9 min readJul 10, 2026
Analogies

Why RelayCommand Exists

RelayCommand, also called DelegateCommand in Prism, is a single generic ICommand implementation that takes an Action (or Action<object>) for Execute and an optional Func<bool> (or Func<object, bool>) for CanExecute, then implements CanExecuteChanged for you. Instead of writing a new class per action as shown for SaveDocumentCommand, a ViewModel just instantiates 'new RelayCommand(Save, CanSave)' and exposes it as a public property, cutting dozens of lines of repetitive plumbing down to a single expression per command across the entire application.

🏏

Cricket analogy: RelayCommand is like a bowling machine at a cricket academy: instead of a new coach demonstrating every delivery type by hand, you feed the machine parameters, line, length, swing, and it reliably reproduces the action for every batter's net session, just as RelayCommand reproduces the Execute/CanExecute plumbing for every action.

Implementing a Generic RelayCommand

A practical RelayCommand stores the Execute and CanExecute delegates in readonly fields set through the constructor, implements CanExecute by returning true when no predicate was supplied (a common convenience default), and typically exposes a RaiseCanExecuteChanged method the ViewModel can call explicitly rather than relying solely on CommandManager.RequerySuggested, giving finer control over when the UI re-checks state. Many implementations also offer a generic RelayCommand<T> variant so CommandParameter values arrive already cast to the correct type instead of forcing manual casting inside every Execute delegate.

🏏

Cricket analogy: It's like a franchise's central scouting database: instead of every team relying on the umpire's ad hoc signal (RequerySuggested) to know a player's fitness status, the physio explicitly pushes an update (RaiseCanExecuteChanged) the moment a fitness test result changes.

csharp
public class RelayCommand : ICommand
{
    private readonly Action _execute;
    private readonly Func<bool> _canExecute;

    public RelayCommand(Action execute, Func<bool> canExecute = null)
    {
        _execute = execute ?? throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;

    public void Execute(object parameter) => _execute();

    public event EventHandler CanExecuteChanged;

    public void RaiseCanExecuteChanged() =>
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

// Usage inside a ViewModel
public ICommand SaveCommand { get; }

public DocumentViewModel()
{
    SaveCommand = new RelayCommand(Save, () => IsDirty && !IsSaving);
}

private void Save()
{
    IsSaving = true;
    // persist changes...
    IsSaving = false;
    IsDirty = false;
}

RelayCommand vs. Framework-Provided Commands

Modern MVVM toolkits ship their own battle-tested RelayCommand: the CommunityToolkit.Mvvm package provides RelayCommand and RelayCommand<T> plus source-generator attributes like [RelayCommand] that auto-generate command properties from marked methods, while Prism offers DelegateCommand with an ObservesProperty method that automatically wires CanExecuteChanged to a specific property's change notifications. Choosing between hand-rolling your own RelayCommand and adopting a toolkit's version is mostly about consistency and reduced boilerplate; the underlying contract with ICommand and the View's binding syntax remain identical either way.

🏏

Cricket analogy: It's like choosing between a club-made bowling machine and a certified BCCI-approved one used at national academies, both fire deliveries, but the certified version has already been stress-tested across thousands of sessions.

The CommunityToolkit.Mvvm [RelayCommand] source generator lets you write a plain method like 'private void Save()' and annotate it with [RelayCommand]; at compile time it generates a public SaveCommand property of type IRelayCommand, eliminating manual command wiring almost entirely.

RelayCommand's default CanExecute of 'true' when no predicate is supplied means forgetting to pass a CanExecute delegate silently makes the command always enabled. This is easy to miss in code review and can let users trigger actions, like Save, when the ViewModel is in an invalid state.

  • RelayCommand (or DelegateCommand) is a reusable, generic ICommand implementation driven by Execute and CanExecute delegates.
  • It removes the need to hand-write a new ICommand class for every ViewModel action.
  • RaiseCanExecuteChanged gives explicit, precise control over when the UI re-checks command state.
  • A generic RelayCommand<T> variant avoids manual casting of the CommandParameter inside Execute.
  • CommunityToolkit.Mvvm's [RelayCommand] source generator can eliminate manual command property boilerplate entirely.
  • Prism's DelegateCommand offers ObservesProperty to auto-wire CanExecuteChanged to specific property changes.
  • Omitting the CanExecute predicate defaults the command to always enabled, a common source of bugs.

Practice what you learned

Was this page helpful?

Topics covered

#NET#MVVMDesignPatternStudyNotes#MicrosoftTechnologies#TheRelayCommandPattern#RelayCommand#Pattern#Exists#Implementing#StudyNotes#SkillVeris