KeyTrigger Not Firing

May 28, 2010 at 9:11 AM
Edited May 31, 2010 at 6:16 AM

My aim here is that per screen (UserControl taking up entire navigation control), i want to capture keypresses that trigger certain commands.  Focus and shortcut keys are sore points for me in WPF, which are not specific to nRoute as such, but im asking you the question since you provide a KeyTrigger and seem to have it working fine in your examples :)  There is a post here http://apocryph.org/2006/09/10/wtf_is_wrong_with_wpf_focus/ that talks about WPFs strange focus behaviour which may or may not be related to this issue, but it certainly has affected my shortcut keys in the past due to the way WPF routes the key presses.  Due to this issue i have had to implement my own SetFocusAction, rather than use your inbuilt one, that implements the hack mentioned in the article.  In short, i cannot seem to get KeyTrigger to fire when the correct key combination is pressed in the UserControl, even if i give it focus manually.

My program structure is essentially a window hosting a NavigationControl.  This navigation control then navigates between various views, that are defined as UserControls.  These UserControls may compose of further UserControls or not.  I am defining my key tiggers in the view UserControls that are navigated to, like this:

<i:Interaction.Triggers>
    <e:KeyTrigger Key="F5">
        <n:ExecuteCommandAction  Command="{Binding RefreshAction, Mode=OneWay}" />
    </e:KeyTrigger>
</i:Interaction.Triggers>

This does not work at all.  The keys used to work when i used a different approach using a combination of CommandRelay resources, UserControl.InputBindings and BridgeCommandBehaviors like so (Apologise for mistakes, this was typed from memory):

<UserControl.Resources>
    <n:CommandRelay x:Key="RefreshCommandRelay" />
</UserControl.Resources>

<i:Interaction.Behaviors>
    <n:BridgeViewModelBehavior />
    <n:BridgeCommandBehavior CommandRelay="{StaticResource RefreshCommandRelay}" CommandSource="{Binding RefreshCommand}" />
</i:Interaction.Behaviors>

<UserControl.InputBindings>
    <KeyBinding Key="F5" Command="{StaticResource RefreshCommandRelay}">
</UserControl.InputBindings>

This approach was a little fragile though - it would work fine, but only when the UserControl had focus.  Since WPF insisted on starting with focus on the container, i used a trick found elsewhere to set  the focus to the first focusable control in the nRoute OnInitialised() methods of each ViewModel.  So my question is two-fold - how you managed to get your stuff to work without any such trickery and why my <KeyTrigger> approach is not working.  Any help is much appreciated.

May 31, 2010 at 7:23 AM
Edited May 31, 2010 at 7:38 AM

Update:  I found that it works if i assign any key combination to the <KeyTrigger> that does not use an ALT modifier.  So 'F5' and 'Ctrl + L' both work but not 'Alt + L'

Coordinator
Jun 1, 2010 at 10:09 AM

Have you tried using nRoute's KeyTrigger? It provides a bit more options/flexibilty. Also, I'm gonna test using with Alt in WPF - though, from my experience I can tell that in Silverlight using Alt+key combo causes the browser's shell to gain the focus. However, this is not consistent across browsers, so I've stoped using it - Ctrl+key works, Alt+Ctrl+key works too, even Alt+Shift+key modifier works.

Anyway, I'll double check about using just the alt modifier in WPF - it should work..
Rishi

Jun 1, 2010 at 2:03 PM

I should have mentioned that i have tried this with both nRoute and Expression versions of <KeyTrigger> - both exhibit the same behavior so its not an nRoute specific problem.  It seems that the issue is that pressing Alt is causing WPF to activate some other form of hotkey mechanism, as when Alt + anything is pressed it generates a Windows error 'ding' noise as if an operation was unsuccessful (rather than just the trigger not firing with no effects at all).  I thought it might be mnemonics (ie - RecognizesAccessKey=true was set on some of the buttons, which allows an underscored character in the button text to be used as an Alt + XXX hotkey) but disabling mnemonics by setting RecognizesAccessKey=false still did not work.  I dont have a menu so its not that either.  I would be happy to use Ctrl + XXX for all hotkeys, but the client has specified a specific set of hotkeys that align with their existing legacy application, hence my desire to get this to work.  Appreciate your help.