Ribbon Buttons not enabling based on CommandParameter

Ribbon for WPF Forum

Posted 1 year ago by Neil Larson
Version: 22.1.4
Avatar

I have correctly bound a CommandParameter and Command to a Ribbon Button. 

The button is enabled when the Commands CanExecute method returns true on the first call.

The button is never enabled when the Commands CanExecute method returns true after the initial call returns false.

It appears that the first returned result is the only one that enables the button on the CommandParameter changing.

I can work around this by calling NotifyCanExecuteChanged in the setter of the property used as the CommandParameter, but would prefer not to use a workaround.

I am using .Net 7 and MVVM Community Toolkit if that helps repro it.

Neil

   private RelayCommand<object?> findMultiCueFireCommand;
   public IRelayCommand<object?> FindMultiCueFireCommand => findMultiCueFireCommand ??= new RelayCommand<object?>(FindMultiCueFire, CanFindMultiCueFire);

   public void FindMultiCueFire(object? param)
   {
      if(param is null || param is not CreateMultiCueCommand create)
         return;

      var matches = TheFireFile?.ShowCommands?.OfType<MultiCueFireCommand>().Where(x => x.TheMultiCue == create);
      if(matches != null)
         MainWindowView?.SelectCommandsAndSetFocusToScriptGridCommand(matches);
   }

   public bool CanFindMultiCueFire(object? param)
   {
      if(param is not CreateMultiCueCommand create)
         return false;

      if(TheFireFile == null)
         return false;

      bool retval = (TheFireFile?.ShowCommands?.OfType<MultiCueFireCommand>()?.Any(x => x.TheMultiCue == create) == true);
      log.Error($"{create?.MultiCueName} CanFindMultiCueFire = {retval}");
      return retval;
   }
     <ribbon:Button Name="RibbonFindMQFireBtn" Label="MQ Fire"
                    CommandParameter="{Binding CurrentMultiCueCommand}" 
                    Command="{Binding FindMultiCueFireCommand, Mode=OneWay}" />

Comments (1)

Posted 1 year ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Neil,

Our code will check the CanExecute when the button first loads to determine its enabled state.  After that, we can only know to check its enabled state again when the command's CanExecuteChanged event fires. 

If you look at the source of RelayCommand, you'll see that calling the CanExecute method doesn't raise the CanExecuteChanged event.  You have to manually raise the NotifyCanExecuteChanged event when you feel your CanExecute delegate result will return a new value.


Actipro Software Support

The latest build of this product (v24.1.2) 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.