How can I capture KeyDown event on a WPF Page or UserControl object?

I have/had the same problem. I have a window which hosts a Frame which loads/navigates to various Page's which at their turn contain just 1 UserControl which contains normal Controls/Elements (Labels, Hyperlinks, etc).

what I discovered (after some hours of frustration of course!!!) is that if you do NOT have the focus on one of the Controls/Elements mentioned above the PreviewKeyDown event does NOT fire on the UserControl (stops somewhere at Frame level) but as soon as you put the focus (for instance calling ctrl.Focus() inside the UserCotrol's Loaded event handler) on one of the controls magic happens, it works, the event fires also for the UserControl.

of course thinking of it afterwards this makes enough sense but I am 100% sure this will cacth at least 5 out of 10 people by surprise :) crazy little thing called WPF...

cheers!


Attach to the Window's Event

After the control is loaded, attach to the Window's KeyDown event (or any event) by using Window.GetWindow(this), like so:

The XAML

<UserControl Loaded="UserControl_Loaded">
</UserControl>

The Code Behind

private void UserControl_Loaded(object sender, RoutedEventArgs e) {
  var window = Window.GetWindow(this);
  window.KeyDown += HandleKeyPress;
}

private void HandleKeyPress(object sender, KeyEventArgs e) {
  //Do work
}

I believe that the PreviewKeyDown event is a tunneling routed event, rather than a bubbling one. If that is the case, then if your Page isn't getting the event, the UserControl shouldn't be either since it is below the Page in the visual tree. Maybe try handling it at the top level of your app (Window perhaps?) and see if it is getting the event?

Another option that might help would be to use something like Snoop in CodePlex to figure out where the events are going.

Tags:

Wpf

Keydown