How to capture Ctrl + Tab and Ctrl + Shift + Tab in WPF?
Asked Answered
L

5

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.

Ludlow answered 1/5, 2009 at 21:28 Comment(0)
T
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");
   }
}
Tough answered 1/5, 2009 at 21:40 Comment(7)
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?Ludlow
@siz You can clean up your If statements by using the following syntax: Keyboard.Modifiers.HasFlag(ModifierKeys.Control)Roobbie
Is there a xamly way to do it?Caribou
how to handle Alt + Tab ?Heulandite
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.Ite
This is not that good answer, because on Ctrl + Shift + Tab both if statements are called. That is wrong.Glaser
(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))Shortterm
S
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;
}
Suggest answered 25/5, 2010 at 23:20 Comment(1)
Sadly, this will not handle when the user uses the right ctrl button :-)Campfire
R
8

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

Rossy answered 4/5, 2009 at 16:35 Comment(5)
Interesting. Haven't tried this, but can you please explain why?Tough
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.Rossy
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.Saucedo
@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.Hydrophilic
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).Ite
F
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");
     }
  }
Fagen answered 18/11, 2016 at 12:40 Comment(0)
C
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
           //
        }
    }
Chokecherry answered 17/5, 2016 at 9:59 Comment(2)
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 + TabGlaser
in this case you can set cancel=true; in both statements when press Ctrl+Shift+TabChokecherry

© 2022 - 2024 — McMap. All rights reserved.