How can a ribbon button be updated while app has no focus?

Ribbon for WPF Forum

Posted 8 months ago by Lars Klose
Version: 18.1.0673
Avatar

Hi,

is it possible to programatically force the ribbon to update one or all buttons, even when the window has no focus because another application is focused?
I noticed that in this case, the CanExecute handlers are not called until the application regains focus. I tried calling CommandManager.InvalidateRequerySuggested() but that didn't have any effect.

(I would like to have a refresh button that is visibly updated even when the app is not focused. The reason is that the app is regularly used side-by-side with another application, that produces data which may be loaded using that button)

Thanks!

Comments (6)

Posted 8 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Lars,

In general, the ribbon buttons should be using WPF commands the same as regular WPF buttons do.  I didn't realize thta CommandManager.InvalidateRequerySuggested only works when the application has focus.  With WPF commands the only way to trigger the button enabled states to refresh is to raise the command's CanExecuteChanged event. 

Normally CommandManager.InvalidateRequerySuggested does that, but you could programmatically trigger it too.  The only thing is that you need to raise the event from the command class itself, so you'd have to either be using your own command type or inherit from RibbonCommand so that you can have a RaiseCanExecuteChanged method added.


Actipro Software Support

Posted 8 months ago by Lars Klose
Avatar

Could you elaborate a bit more on your suggestion?

I tried with a command class inheriting from RibbonCommand, but obviously cannot do CanExecuteChanged?.Invoke in the derived class, and a RaiseCanExecuteChanged is not available in RibbonCommand (but only in DelegateCommand).

Am I missing something here...?

Posted 8 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Lars,

Sorry we don't have that method on RibbonCommand.  I meant you would have to add it.  Just a basic RaiseCanExecuteChanged method that raised the event is all.


Actipro Software Support

Posted 8 months ago by Lars Klose
Avatar

Yep, that's exactly what I naively did:

public class ForcedUpdateRibbonCommand : RibbonCommand
{
  public void RaiseCanExecuteChanged()
  {
    CanExecuteChanged?.Invoke(this, new EventArgs());
  }
}

However, raising an event is only possible within the class defining that event, not in the inheriting class:

Error CS0079 The event 'RoutedCommand.CanExecuteChanged' can only appear on the left hand side of += or -= 
Posted 8 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Lars,

I apologize, I thought an inheriting class could also raise it but you're right, C# doesn't allow that.  I tried and received the same error.

From everything I've read online, with routed commands, CommandManager.InvalidateRequerySuggested is the only way to get them to re-evaluate.  And it apparently must be called from the UI thread.  A lot of people who run into issues with the routed commands recommend using DelegateCommand-like implementations (we have one in our Shared Library) where you have more control over the raising of the event.


Actipro Software Support

Posted 8 months ago by Lars Klose
Avatar

For the record: my suspicion of a relation to the window having focus or not was incorrect.
CommandManager.InvalidateRequerySuggested also works when the window/application has no focus, but it has to be called from the UI dispatcher, i.e. via Application.Current.Dispatcher.BeginInvoke. Then, CanExecute is evaluated as expected, regardless of the focus.

The latest build of this product (v2019.1 build 0682) was released 2 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.