How does CommandManager.RequerySuggested work?

Andrei Rînea picture Andrei Rînea · May 4, 2010 · Viewed 18.9k times · Source

The MSDN only states that

Occurs when the CommandManager detects conditions that might change the ability of a command to execute.

However I can't seem to find any traces of how this works, what I should be aware of / avoid etc... Does it just listen for input? (i.e.: mouse moves, keys pressed and so on)

Answer

gehho picture gehho · May 4, 2010

I cannot tell you exactly what events the CommandManager listens to. However, I can tell you that you should be careful when using the CommandManager in connection with asynchronous operations. I had the following problem when I used the CommandManager in my ICommand implementations:

I had a button bound to an ICommand which triggered an asynchronous operation which increased a value. Now, the button/ICommand should be disabled (i.e. its CanExecute() method should return false) if the value had reached a certain limit. The problem was: The CommandManager called my CanExecute() method right after the button had been clicked and the asynchronous operation had been started. This asynchronous operation did not take long, but it was long enough to get its result after the CommandManager's check, so that the limit check in CanExecute() was done using the old value. Therefore, the button remained enabled although the limit was actually reached. The funny thing was, after you clicked anywhere in the UI, the button now got disabled because the CommandManager checked the ICommand once again and now the new value was checked against the limit. Actually, I think the CommandManager waited around 50ms after the button click until it performed the check of the ICommand, but I am not quite sure about that.

My solution was to force the CommandManager to check the ICommand again by calling the CommandManager.InvalidateRequerySuggested method in my ViewModel right after I received the result of the async operation.
Update: Please note that this method must be called on the UI thread, otherwise it will have no effect! (Thanks to midspace for this comment)