69

What would be some sample code that will trap the Ctrl+Tab and Ctrl+Shift+Tab for a WPF application?

We have created KeyDown events and also tried adding command bindings with input gestures, but we were never able to trap these two shortcuts.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
FarrEver
  • 2,951
  • 5
  • 29
  • 24

5 Answers5

101

What KeyDown handler did you have? The code below works for me. The one that gives me trouble is: Alt + Tab, but you didn't ask for that :D

public Window1()
{
   InitializeComponent();
   AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)HandleKeyDownEvent);
}

private void HandleKeyDownEvent(object sender, KeyEventArgs e)
{
   if (e.Key == Key.Tab && (Keyboard.Modifiers & (ModifierKeys.Control | ModifierKeys.Shift)) == (ModifierKeys.Control | ModifierKeys.Shift))
   {
      MessageBox.Show("CTRL + SHIFT + TAB trapped");
   }

   if (e.Key == Key.Tab && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
   {
      MessageBox.Show("CTRL + TAB trapped");
   }
}
Ulf Gjerdingen
  • 1,414
  • 3
  • 16
  • 20
Szymon Rozga
  • 17,971
  • 7
  • 53
  • 66
  • Siz, thanks...that does work for our WPF. We also have an XBAP that we need to trap this for and it doesn't appear to work on the XBAP. Any ideas on how to do this with an XBAP as well? – FarrEver May 04 '09 at 14:49
  • 1
    Is there a xamly way to do it? – Shimmy Weitzhandler Jul 06 '11 at 08:08
  • 15
    @siz You can clean up your If statements by using the following syntax: `Keyboard.Modifiers.HasFlag(ModifierKeys.Control)` – Pakman Aug 16 '10 at 17:28
  • 1
    how to handle Alt + Tab ? – Sagar Pilkhwal Nov 30 '15 at 15:06
  • 1
    So many up-votes and it seems to work, yet this is WRONG. If you comment out first "if" block, the second one will still capture Ctrl+Shift+Tab. MessageBox causes the control to lose focus. If you leave both "if" blocks uncommented and replace MessageBox with Console.WriteLine for Ctrl+Shift+Tab, you'll see "CTRL + TAB trapped", too. You can't reset flags on Keyboard.Modifiers before comparison. You have to compare the exact value. – Aoi Karasu May 08 '16 at 22:40
  • 1
    This is not that good answer, because on Ctrl + Shift + Tab both if statements are called. That is wrong. – Devid Oct 10 '16 at 07:40
  • 1
    `(Keyboard.Modifiers & (ModifierKeys.Control | ModifierKeys.Shift)) == (ModifierKeys.Control | ModifierKeys.Shift)` also captures Ctrl+Shift+Alt, so it seems better to me to use `(Keyboard.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift))` – rayzinnz Jun 22 '17 at 05:48
31

Gustavo's answer was exactly what I was looking for. We want to validate input keys, but still allow pasting:

protected override void OnPreviewKeyDown(KeyEventArgs e)
{
   if ((e.Key == Key.V || e.Key == Key.X || e.Key == Key.C) && Keyboard.IsKeyDown(Key.LeftCtrl))
      return;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mikeB
  • 310
  • 3
  • 7
8

You have to use KeyUp event, not KeyDown...

Vukašin Manojlović
  • 2,645
  • 2
  • 21
  • 26
Gus Cavalcanti
  • 10,527
  • 23
  • 71
  • 104
  • 2
    Interesting. Haven't tried this, but can you please explain why? – Szymon Rozga May 04 '09 at 19:35
  • 7
    Sure Siz. When you are trying to capture 2 or more key strokes at the same time you cannot use KeyDown checking for e.Key because it captures one key at a time. If KeyDown is necessary, like doing something when the user is holding down a key combination for example, you should use KeyDown and the Keyboard class, specifically IsKeyDown(), testing for specific keys. – Gus Cavalcanti May 05 '09 at 16:26
  • 1
    Sorry, I don't understand what you're trying to say here. The KeyUp event also only passes a single Key value in e.Key. Can you give a specific example where handling KeyUp instead of KeyDown would be better for "capturing 2 or more keystrokes at the same time"? Thanks. – Ray Burns Nov 07 '09 at 19:25
  • 5
    @RayBurns The idea behind capturing KeyUp is that at the moment of KeyUp, all "modifier" keys are already pressed. You only need checking them to figure out the whole key combination within the same handler. If you work with KeyDown instead, you have hard time telling Shift+Ctrl (e.g. change keyboard layout) from Shift+Ctrl+A. – Be Brave Be Like Ukraine Nov 23 '12 at 05:55
  • Both Up and Down events are exposed for a reason. All depends on the use case. In some cases using Down is much better, eg. you want to repeat action bound to they key as long as it's pressed without the need of tapping they key repeatedly. You'd prefer to use Up, if you want to prevent from action firing more then once by mistake (the key is pressed for too long by mistake). – Aoi Karasu May 08 '16 at 22:49
5

Working version of Szymon Rozga answer (sorry, I can't comment). We don't look on Alt, but it's accounting can be simply added at first if

  public View()
  {
     InitializeComponent();
     AddHandler(Keyboard.PreviewKeyDownEvent, (KeyEventHandler)controlKeyDownEvent);
  }

  private void controlKeyDownEvent(object sender, KeyEventArgs e)
  {
     if (e.Key == Key.Tab && Keyboard.Modifiers.HasFlag(ModifierKeys.Control))
     {
        if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
           MessageBox.Show("CTRL + SHIFT + TAB trapped");
        else
           MessageBox.Show("CTRL + TAB trapped");
     }
  }
Lev
  • 811
  • 12
  • 13
1

Hi you can use this on keydown event

 private void OnButtonKeyDown(object sender, KeyEventArgs e)
    {
        if(Keyboard.IsKeyDown(Key.LeftCtrl) && Keyboard.IsKeyDown(Key.Tab) && Keyboard.IsKeyDown(Key.LeftShift))
        {
           //
           // TODO: somthing here
           //
        }
    }
luka
  • 605
  • 8
  • 15
  • The problem here is also that if I add one more if statement with (Keyboard.IsKeyDown(Key.LeftCtrl) && Keyboard.IsKeyDown(Key.Tab)). Both statements will be executed if I press Ctrl +Shift + Tab – Devid Oct 10 '16 at 07:48
  • in this case you can set cancel=true; in both statements when press Ctrl+Shift+Tab – luka Oct 12 '16 at 08:46