I've been using Josh Smith's implementation of RelayCommand in a couple of large projects for some years now. However today I've come across a scenario where the CanExecute on one of my commands isn't refreshing. I'm at a loss as to what's causing it - the view-model isn't doing anything that I haven't done dozens of times already.
The VM's constructor creates a couple of commands. The first one is a "start" command:-
StartCommand = new RelayCommand(o => StartAsync(), o => true);
The StartAsync() method looks like this:-
private async void StartAsync()
{
IsRunning = true;
await Task.Run(() => SomeLongRunningProcess(); }
IsRunning = false;
}
There is also a "save" command:-
SaveCommand = new RelayCommand(o => Save(), o => !IsRunning);
('IsRunning' is a bog-standard property, implementing INotifyPropertyChanged. As well as being used for the "CanExecute" delegate, it's also bound to the IsEnabled property of a few controls in the view to enable/disable them).
When I click my "Start" button (bound to 'StartCommand'), the "Save" button is correctly disabled. The b/g process runs to completion, then IsRunning is set to false, but this doesn't trigger the "Save" button to become enabled. It only enables if I click somewhere on my view.
(The controls whose IsEnabled
property is bound to the VM IsRunning
property do enable and disable correctly, by the way).
I've come across a few SO articles about this, but nothing really explains why this happens. My workaround was to bind the button's IsEnabled
property to 'IsRunning', but it's frustrating that this particular view refused to play ball. Any thoughts on what might be causing this? Common sense says it's something specific to this view/VM, but I'm stumped (and I'm not going to post the code here - there's too much of it).