0

I've got a ListView with some KeyBindings that let the user move and delete entries with keyboard shortcuts. However, I don't want the bindings to be accessible all the time.

The button controls to add, remove, and move entries have their visibility tied to the selection of a ComboBox (only certain users can edit). I want the keyboard shortcuts to deactivate based on the box selection as well.

I haven't been able to find any info on whether or not this is possible yet. What do you guys think?

<ComboBox x:Name="TesterIdentityBox" ItemsSource="{Binding Path=TesterIdentityList, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" SelectedItem="{Binding Path=TesterIdentitySelection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  SelectedIndex="{Binding TesterIdentityIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<ListView ItemsSource="{Binding TestViewList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="{Binding SelectedTestIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Path=SelectedTest}">
    <ListView.InputBindings>
        <KeyBinding Key="Up" Command="{Binding Path=MoveTestUpCommand}" CommandParameter="{Binding Path=SelectedTest.Description}" />
        <KeyBinding Key="Down" Command="{Binding Path=MoveTestDownCommand}" CommandParameter="{Binding Path=SelectedTest.Description}" />
        <KeyBinding Key="Delete" Command="{Binding Path=RemoveTestCommand}" />
    </ListView.InputBindings>

I used Style Setters with DataTriggers to alter the command buttons' visibility, but I don't know what (if anything) is the equivalent for a non-visual element like a KeyBinding.

Nightmare Games
  • 2,205
  • 6
  • 28
  • 46

1 Answers1

1

The simplest way in this case would be to implement the CanExecute() methods in your MoveTestUpCommand, MoveTestDownCommand and RemoveTestCommand. This methods should return false when you don't want the user to be able to do those things. So, your KeyBindings will have no effect since the commands will not be executed.

If your buttons' Command properties are also bound to these commands, these buttons will then update their availability (IsEnabled property) automagically according to the CanExecute() return values. To update the view state from the viewmodel, simply call the RaiseCanExecuteChanged() methods on corresponding commands (this depends on your ICommand implementation however).

To set the button's visibility according to its availability, you could use something like:

<Button 
  Command = "{Binding SampleCommand}" 
  Visibility = "{Binding IsEnabled, RelativeSource = {RelativeSource Self}, Converter = {StaticResource BooleanToVisibilityConverter}}"/>

There is an implementation of the BooleanToVisibilityConverter in System.Windows.Controls.

dymanoid
  • 14,771
  • 4
  • 36
  • 64
  • Yes, I forgot about CanExecute. I almost never use it, but it works great here. I decided not to change the other bindings around since I've already got a visibility checker in place, but I'll remember that for next time. Thanks a lot. – Nightmare Games Mar 02 '15 at 19:21
  • After some testing, I noticed my "Remove" button was disabled, like you mentioned, but it was disabled all the time, even when the CanExecute was true. I thought it might be from the UI not updating, but my implementation doesn't seem to include the RaiseCanExecuteChanged function. The easy solution for me was to simply erase the CanExecute and change it to a check inside the remove function itself. Now the key and button both have the correct behavior. – Nightmare Games Mar 03 '15 at 01:17
  • This problem came back to haunt me after someone specifically requested I go back to the CanExecute method. After starting a new question, I figured out it was a combination of logic errors on my part: http://stackoverflow.com/questions/28910262/wpf-canexecute-is-always-disabled/28974807#28974807 – Nightmare Games Mar 10 '15 at 22:00