1

Basicaly I am facing very similar problem to the question WPF - how to hide menu item if command's CanExecute is false?, the accepted answer uses a clever workaround to bind to the IsEnabled instead of CanExecute() result. Alas IsEnabled workaround would not work in my case:
I have a collection of KeyBindings gathered from the VisualTree during the PreviewGotKeyboardFocus event from various controls, because of this I can have no assumption whether the original keybinding's element is disabled for some other reason (e.g. IsBeingLoaded binding) or even if the element is not disabled at all (e.g. Grid does not disable if cannot execute its KeyBindings). How can I bind to the KeyBinding.Command's current CanExecute() value?

public class ContextHelperVM : ViewModelBase 
{
    public ObservableCollection<KeyBinding> ContextEffectiveKeybindings { get; }
    // KeyBinding list loading, maintaining, etc. pseudocode
    // Keybindings = FocusedElement.TraverseToParentWidnow().GatherKeyBindings();
}

in the ContextHelperView.xaml I would like to set Opacity to non-executable KeyBindings

<ItemsControl ItemsSource="{Binding ContextEffectiveKeybindings}">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding Key}"/>
         <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Command.????}" Value="False"><!--how to bind here??-->
               <Setter Property="Opacity" Value="0.5">
            <DataTrigger>
         </DataTemplate.Triggers>
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

How can I fix the code so that the Opacity is correctly set for KeyBinding.Commands that cannot be executed?

wondra
  • 3,271
  • 3
  • 29
  • 48
  • Usually you would base your `triggers` on something else than the command. With a `RelayCommand`, you will bind the `CanExecute` like this: `new RelayCommand(Method, ()=> BooleanWhichWillIndicateIfCanExecuteOrNot);`, and your trigger you can bind to the same `bool` – Nawed Nabi Zada Jan 16 '20 at 11:10
  • @NawedNabiZada generally speaking yes, but I dont think that is not possible in this case. None of the `KeyBinding` commands are members of `ContextHelperVM` and can come from various controls, viewmodels or even different assemblies. Moreover, the DataContexts are different from the original place from where it was gathered from. My helper function gathers *all* keybindings by traversing from focused control to the root (Window). My viewmodel should be able to display them, (which it does) but does not seem to have access to the executability thus the problem here. – wondra Jan 16 '20 at 11:27
  • @NawedNabiZada 2/2 it is great advice and it is actually exactly what I do on the 'origin' place. E.g. `new RelayCommand(SavePeople, ()=> CanSavePeople)` in `PeopleVM`, and it is used in xaml in the PeopleV ``. But `ContextHelperV` is a completely separate entity with no relation to the original command source (`PeopleV`) - it just displays any keys that you can press and do something. – wondra Jan 16 '20 at 11:42
  • You've misspelled Binding as Bidning. – Kevin Cook Jan 16 '20 at 21:16

0 Answers0