Search code examples
c#winformscustom-controlsonkeydown

Ctrl+PageUp/Down does something weird?


I'm implementing my own control in Windows Forms. It's a treeview, so I have to implement navigation keys: arrows, page up/down and their combinations with shift and control to handle multiselection.

Recently I discovered, that combination of Ctrl + PageUp/PageDown does something weird. Primarily, it does not trigger OnKeyDown (only ControlKey is captured). Additionally, no other keys are captured until I click the control with the mouse (it looks like it loses the focus) I've implemented IsInputKey:

    protected override bool IsInputKey(Keys keyData)
    {
        // Capture arrow keys
        if ((keyData & (Keys.Up | Keys.Down | Keys.Left | Keys.Right | 
            Keys.PageDown | Keys.PageUp | Keys.ControlKey | Keys.Control)) != 0)
            return true;
        else
            return base.IsInputKey(keyData);
    }

There is nothing special in OnKeyDown handler.

What is going on?


Solution

  • Your code does work. I am receiving OnKeyDown action:

    protected override void OnKeyDown(KeyEventArgs e) {
      if (e.KeyData == (Keys.Control | Keys.PageDown)) {
        // Control + Page Down
      } else if (e.KeyData == Keys.PageDown) {
        // Page Down
      }
      base.OnKeyDown(e);
    }
    

    Here is a stripped down version of your code that works:

    public class VirtualTreeView : UserControl {
    
      protected override void OnKeyDown(KeyEventArgs e) {
        if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.PageUp || e.KeyCode == Keys.PageDown || e.KeyCode == Keys.Home || e.KeyCode == Keys.End) {
          if (e.Control) {
            MessageBox.Show("Ctrl - " + e.KeyCode.ToString());
          }
        } else
          base.OnKeyDown(e);
      }
    
      protected override bool IsInputKey(Keys keyData) {
        // Capture arrow keys
        if ((keyData & (Keys.Up | Keys.Down | Keys.Left | Keys.Right | Keys.PageDown | Keys.PageUp | Keys.ControlKey | Keys.Control)) != 0)
          return true;
        else
          return base.IsInputKey(keyData);
      }
    }
    

    Pressing Control-PageUp shows a message box.