6

I have a WPF screen that has half a dozen buttons. I'd like to associate each with a keybinding. They are all ICommand driven via MVVM.

I currently have the keybindings bound to the events and not the actual buttons:

<UserControl.InputBindings>
        <KeyBinding Key="N"  Command="{Binding MyCommand}"/>

However, for any Keybinding to work I have to set at least 1 button to focus in the codebehind. I'd really like to not do this because each button/command has different rules on if it's active or not and I have focus animation that I'd prefer wasn't active on page load.

Is this possible or do I have to set focus?

itchi
  • 1,683
  • 14
  • 30

3 Answers3

14

You just need to set usercontrol's focusable to true, because some element doesn't have it to true by default

<UserControl Focusable="True">

Then you have to set this.Focus() in the loaded event of the user control

MaRuf
  • 1,834
  • 2
  • 19
  • 22
  • 3
    You can still do it in xaml. use System.Windows.Interactivity and :Expression.Samples.Interactivity – jrwren Nov 15 '11 at 17:56
  • 1
    Works great, thanks! And let's not obsess too much over not using code-behind. This is a case where it's strictly UI and that's where it belongs (though the interaction.triggers thing above is fine too, but I just tend to use those when I need to run a command in a viewmodel). – MetalMikester Sep 19 '13 at 15:30
1

It might be that you do need to focus on some element to get it to work, but perhaps you could just set focus on your entire UserControl without visual feedback? You could also try setting the focus to an invisible element if that does not work.

BTW, there seems to have been a similar question on here before: WPF MVVM KeyBinding not being recognized right away and not always working

Community
  • 1
  • 1
Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
0

Are you Hosting you UserControl in a Window.... is that is the Case yu can use....

<Window x:Class="GM.Powertrain.DOEMenu.ViewLayer.AboutScreen"
Height="460" Width="370" 
WindowStartupLocation="CenterScreen"
ShowInTaskbar="False"
HorizontalAlignment="Center" 
VerticalAlignment="Center"
ResizeMode="NoResize"      
FocusManager.FocusedElement="{Binding ElementName=UserControlName}" 
                   Behaviors:WindowCloseOnEscapePressBehavior.EscapeClosesWindow="True" Behaviors:Help.Filename="Help/DOEMenuHelp.chm" Behaviors:Help.Keyword="About Screen">
<UserControl Name=UserControlName>
   <KeyBinding Key="N"  Command="{Binding MyCommand}"/>
</UserControl>
</Window>

Your Keybinding should work this way...

Ankesh
  • 4,847
  • 4
  • 38
  • 76
  • Hmm.. Yeah, I'm using a contentcontrol and inserting the usercontrol via prism region. But I've tried on the window and the usercontrol to set the usercontrol as the focus and it didn't work. I may try a small test project and use this approach. – itchi Nov 15 '11 at 17:25
  • I'm suprised FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}} Doesn't work in the actual usercontrol. But setting this.Focus() does work. – itchi Nov 15 '11 at 17:42