3

Closed

RelayCommand - RaiseCanExecuteChanged: Changed behavior

description

Hi,

After chagning from v3 SP1 to 4, I noticed that the RelayCommand's CanExecute callback was not called anymore. Seems that the new implementation does not anymore use the CommandManager.InvalidateRequerySuggested method, which may be the reason for the changed behavior.

I cannot unfortunately post any samples, but just wanted to report that the current implementation may cause issues for people migrating to the latest version.

Matti
Closed Oct 13, 2014 at 12:56 PM by lbugnion

comments

jberger wrote Oct 10, 2011 at 2:35 AM

I think I recall that Laurent had mentioned that the CommandManager was slightly unreliable.

friskm wrote Oct 10, 2011 at 11:04 AM

Yes, He mentions the unreliability in his blog, but gives no scenarios where this would occur. To me it has worked just perfectly. There seems to be some ideological reasons for the change also. It would be good if the CommandManager could still be used at least optionally.

It seems to me that the new implementation requires much more manual coding with messaging or events to trigger the CanExecute delegate.

Matti

lbugnion wrote Oct 23, 2011 at 5:38 PM

Hi,

The issue with the CommandManager in WPF is a pet peeve of mine. It is not possible to be sure that it will fire (and if it does, it often fires too much, on every single UI event). As such I prefer the Silverlight implementation where one needs to raise the CanExecuteChanged event explicitly.

This is however a breaking change, and breaking changes are never a happy occurrence. I am considering biting the bullet and reverting to the old implementation just to avoid the breaking change. Stay tuned.

Cheers,
Laurent

VicKlien wrote Nov 5, 2011 at 5:00 AM

I don't understand the following about this change:

I downloaded and installed the current GalaSoft.MvvmLight.V4beta1.msi
("uploaded Oct 7"). Reflector shows RelayCommand.CanExecuteChanged
in the WPF4.dll is using the "newer" technique that does NOT use
CommandManager.RequerySuggested.
add
{
    EventHandler handler2;
    EventHandler canExecuteChanged = this.CanExecuteChanged;
    do
    {
        ... more stuff here ...
    }
    while (canExecuteChanged != handler2);
}
But when I look at the source code that is apparently supposed to
correspond to the above GalaSoft.MvvmLight.V4beta1.msi
(change set 7083e76f9123) it shows the "old" technique:
add
{
    if (_canExecute != null)
    {
        CommandManager.RequerySuggested += value;
    }
}
Shouldn't this change set be what GalaSoft.MvvmLight.V4beta1.msi
uploaded Oct 7 was built from?

Thanks,
Vic

VicKlien wrote Nov 5, 2011 at 5:09 AM

Oops. My mistake. I was comparing the older V3 source code with the newer V4beta1 MSI.
Too bad there is no way to erase my previous incorrect comment.

Vic

VicKlien wrote Nov 5, 2011 at 8:42 PM

Update:

My "solution" to the undesired (to me) V4beta1 changes to the implementation of RelayCommand under WPF was to create my own modified V4beta1 release. I just replaced the stock V4beta1 RelayCommand.cs and RelayCommandGeneric.cs with the stock V3 copies of those files. So now I get the other improvements of V4beta1, without the changed RelayCommand.

This causes some of the stock V4beta1 unit tests to fail (as you would expect), but otherwise I haven't seen any negative side effects.

Vic