CommandManager.InvalidateRequerySposed does not launch RequerySposed

I am trying to test a class that uses CommandManager.RequerySuggested , and noticed that calling CommandManager.InvalidateRequerySuggested does not start RequerySuggested from my test. Is there a reason for this and how to solve this problem? Is CommandManager initialization CommandManager ?

Code to reproduce the problem:

 [Test] public void InvalidateRequerySuggested_TriggersRequerySuggested() { bool triggered = false; CommandManager.RequerySuggested += (s, a) => triggered = true; CommandManager.InvalidateRequerySuggested(); Thread.Sleep(1000); // Just to be sure Assert.True(triggered); // Never true } 
+4
source share
3 answers

As stated in msdn in the notes here , CommandManager.RequerySuggested contains only a weak reference to the event. In your unit test, the lambda garbage expression is compiled.

Try the following:

 bool triggered; EventHandler handler = (s, e) => triggered = true; CommandManager.RequerySuggested += handler; CommandManager.InvalidateRequerySuggested(); GC.KeepAlive(handler); Assert.IsTrue(triggered); 

Update

From some further research, I believe that I have identified the problem.

CommandManager.InvalidateRequestSuggested() uses the current dispatcher for an asynchronous asynchronous event.

Here is the solution:

 bool triggered; EventHandler handler = (s, e) => triggered = true; CommandManager.RequerySuggested += handler; CommandManager.InvalidateRequerySuggested(); // Ensure the invalidate is processed Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new Action(() => { })); GC.KeepAlive(handler); Assert.IsTrue(triggered); 
+3
source

Another possible reason for this behavior: I found that we need to subscribe to the RequerySuggested event using the same dispatcher as the one that is called by InvalidateRequerySuggested .

I created several objects in a thread other than the UI that subscribed to this event, and the event did not raise. The change

 CommandManager.RequerySuggested += HandleRequerySuggestedSuggested; 

to

 Application.Current.Dispatcher.Invoke((Action)(() => CommandManager.RequerySuggested += HandleRequerySuggestedSuggested)); 

decided it for me.

+1
source

Just keep a link to your event handler

0
source

Source: https://habr.com/ru/post/1487827/


All Articles