DEV Community

Cover image for Fixing a RelayCommand Whose CanExecute Does Not Update the Button State in WPF
s-iguchi09
s-iguchi09

Posted on Edited on Originally published at s-iguchi09.github.io AI-assisted

Fixing a RelayCommand Whose CanExecute Does Not Update the Button State in WPF

You fill in the required field, CanExecute now returns true, and the Save button stays grey. A hand-written RelayCommand declares CanExecuteChanged but never raises it, so the button never asks again.

This is a short summary. The full article, with a table of what each call does to Button.IsEnabled on .NET 10, is here:
Fixing a RelayCommand Whose CanExecute Does Not Update the Button State in WPF

What the measurements show

  1. A new CanExecute result alone changes nothing. The button re-queries only when CanExecuteChanged fires.
  2. The way you raise it has to match the implementation. CommandManager.InvalidateRequerySuggested() and ordinary typing reach only a command that forwards to RequerySuggested. A command with its own event ignores both and needs its own raise method.

The fix

When a view model property decides executability, keep your own event and raise it from the setter:

public event EventHandler? CanExecuteChanged;

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

// In the view model
set { _name = value; SaveCommand.RaiseCanExecuteChanged(); }
Enter fullscreen mode Exit fullscreen mode

When executability follows focus or selection instead, forward add/remove to CommandManager.RequerySuggested. The full article covers when each fits, the cost of requerying every connected button, and why both raises belong on the UI thread.

A Japanese version is also available.

Related Articles

Top comments (0)