pressing arrow keys as hot-keys changes control focus

I want to define the Left and Right arrow keys as "hot keys" in my form. I've handled KeyDown, and I set the Handled property of the event, but if the current focus is on a button, radio, check box, etc, then the arrow keys cycle the input focus through controls on the form, or within the same group box.

How can I disable this behavior


Answer this question

pressing arrow keys as hot-keys changes control focus

  • Guillermina Feliciano

    Well, here's the code I used, so feel free to try it.  It catches left and right and throws up a MessageBox when it's caught.  The code works -- I just tested it myself -- so maybe it'll help.

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;

    namespace WindowsApplication12
    {
       /// <summary>
       /// Summary description for Form1.
       /// </summary>
       public class Form1 : System.Windows.Forms.Form
       {
          private System.Windows.Forms.Button button1;
          private System.Windows.Forms.Button button2;
          private System.Windows.Forms.Button button3;
          private System.Windows.Forms.GroupBox groupBox1;
          private System.Windows.Forms.RadioButton radioButton1;
          private System.Windows.Forms.RadioButton radioButton2;
          private System.Windows.Forms.RadioButton radioButton3;
          /// <summary>
          /// Required designer variable.
          /// </summary>
          private System.ComponentModel.Container components = null;

          public Form1()
          {
             //
             // Required for Windows Form Designer support
             //
             InitializeComponent();

             //
             // TODO: Add any constructor code after InitializeComponent call
             //
          }

          /// <summary>
          /// Clean up any resources being used.
          /// </summary>
          protected override void Dispose( bool disposing )
          {
             if( disposing )
             {
                if (components != null) 
                {
                   components.Dispose();
                }
             }
             base.Dispose( disposing );
          }

          #region Windows Form Designer generated code
          /// <summary>
          /// Required method for Designer support - do not modify
          /// the contents of this method with the code editor.
          /// </summary>
          private void InitializeComponent()
          {
             this.button1 = new System.Windows.Forms.Button();
             this.button2 = new System.Windows.Forms.Button();
             this.button3 = new System.Windows.Forms.Button();
             this.groupBox1 = new System.Windows.Forms.GroupBox();
             this.radioButton1 = new System.Windows.Forms.RadioButton();
             this.radioButton2 = new System.Windows.Forms.RadioButton();
             this.radioButton3 = new System.Windows.Forms.RadioButton();
             this.groupBox1.SuspendLayout();
             this.SuspendLayout();
             // 
             // button1
             // 
             this.button1.Location = new System.Drawing.Point(200, 8);
             this.button1.Name = "button1";
             this.button1.TabIndex = 0;
             this.button1.Text = "button1";
             // 
             // button2
             // 
             this.button2.Location = new System.Drawing.Point(200, 48);
             this.button2.Name = "button2";
             this.button2.TabIndex = 1;
             this.button2.Text = "button2";
             // 
             // button3
             // 
             this.button3.Location = new System.Drawing.Point(200, 88);
             this.button3.Name = "button3";
             this.button3.TabIndex = 2;
             this.button3.Text = "button3";
             // 
             // groupBox1
             // 
             this.groupBox1.Controls.Add(this.radioButton3);
             this.groupBox1.Controls.Add(this.radioButton2);
             this.groupBox1.Controls.Add(this.radioButton1);
             this.groupBox1.Location = new System.Drawing.Point(48, 136);
             this.groupBox1.Name = "groupBox1";
             this.groupBox1.TabIndex = 3;
             this.groupBox1.TabStop = false;
             this.groupBox1.Text = "groupBox1";
             // 
             // radioButton1
             // 
             this.radioButton1.Location = new System.Drawing.Point(3, 16);
             this.radioButton1.Name = "radioButton1";
             this.radioButton1.TabIndex = 0;
             this.radioButton1.Text = "radioButton1";
             // 
             // radioButton2
             // 
             this.radioButton2.Location = new System.Drawing.Point(120, 40);
             this.radioButton2.Name = "radioButton2";
             this.radioButton2.Size = new System.Drawing.Size(72, 24);
             this.radioButton2.TabIndex = 1;
             this.radioButton2.Text = "radioButton2";
             // 
             // radioButton3
             // 
             this.radioButton3.Location = new System.Drawing.Point(8, 64);
             this.radioButton3.Name = "radioButton3";
             this.radioButton3.TabIndex = 2;
             this.radioButton3.Text = "radioButton3";
             // 
             // Form1
             // 
             this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
             this.ClientSize = new System.Drawing.Size(292, 266);
             this.Controls.Add(this.groupBox1);
             this.Controls.Add(this.button3);
             this.Controls.Add(this.button2);
             this.Controls.Add(this.button1);
             this.KeyPreview = true;
             this.Name = "Form1";
             this.Text = "Form1";
             this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
             this.groupBox1.ResumeLayout(false);
             this.ResumeLayout(false);

          }
          #endregion

          /// <summary>
          /// The main entry point for the application.
          /// </summary>
          [STAThread]
          static void Main() 
          {
             Application.Run(new Form1());
          }

          private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
          {
             // You can try uncommenting this code, but it works with the code commented
             //e.Handled = true;
             //MessageBox.Show(e.KeyValue.ToString());
          }

          protected override bool ProcessDialogKey(Keys keyData)
          {
             if (keyData.Equals(Keys.Left) || keyData.Equals(Keys.Right))
             {
                MessageBox.Show("caught");
                return true;
             }
             else
             {
                return base.ProcessDialogKey(keyData);
             }
          }

       }
    }


    -Ari

  • Gwired

    Trapping the modifier keys is just as easy -- just do a bitwise OR on the keyData.Equals() call to check for modifier keys.  So in this example, to use Shift you would change this:if (keyData.Equals(Keys.Left) || keyData.Equals(Keys.Right))to this:if (keyData.Equals(Keys.Left | Keys.Shift) || keyData.Equals(Keys.Right | Keys.Shift))

    Hope this helps.

    -Ari

  • Christian J&amp;#248;rgensen

    I think I'm using some control groups which must hook to something deeper. Thanks for the effort.
  • Rahil Bukhari

    You're right -- there is a mistake in my code.  You should be returning true if you don't want to process the keystroke anymore; otherwise, you want to return the call to the base class's ProcessDialogKeys.  Though interestingly, false worked as well.  Weird.

    Have you set the form's KeyPreview to true   If you haven't, none of this will work.  This allows the form to see the keystrokes before they're processed.

    Hmm... if that doesn't work, let me know.  I wrote a sample app in C# that illustrates this working (actually, that's all it does -- 3 buttons, a groupbox, and 3 radiobuttons, and if you hit left or right you get a messagebox and nothing else).  I can post it here if necessary.

    -Ari

  • Ravindra Vyas

    This example code works great but what if you want to trap the use of a modifier key as well (eg. SHIFT + LEFT ARROW)

    Your help would be much appreciated!

    Thanks Dave

  • harish1981

    Well, from looking at the ProcessDialogKeys, you should be returning True, right  But I tried both, and neither of them seem to work. It's especially visible when a group box and a bunch of radio buttons have the focus.
  • TheGeoff

    Here's what you need to do:  Override the form's ProcessDialogKey method, and return false if the key is Left or Right.  This will prevent the form from sending the keystroke on to the child controls.

    Also, the form's KeyPreview property MUST be set to true.  This allows the form to preview what keys are being pressed before allowing them to be passed on to the appropriate events.

    So what you have is the form's ProcessDialogKey overridden, KeyPreview set to true, and the form's KeyDown event handled.  That should take care of the problem.

    Here's what the ProcessDialogKey method should look like on your form.  It's in C#; let me know if you need it in VB.

    public class MyForm : System.Windows.Forms.Form
    {
       // Normal stuff goes here

       private void MyForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
       {
          // Call your method or whatnot here; this is where you handle the actual key press
          // Set e.Handled as necessary.
       }
       
       protected override bool ProcessDialogKey(Keys keyData)
       {
          if (keyData.Equals(Keys.Left) || keyData.Equals(Keys.Right))
             return false;
          else
             // Pass it on to the base class for processing
             return base.ProcessDialogKey(keyData);
       }
    }


    More info on ProcessDialogKey is available here:
    <a href="http://msdn.microsoft.com/library/default.asp url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclassprocessdialogkeytopic.asp">http://msdn.microsoft.com/library/default.asp url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclassprocessdialogkeytopic.asp</a>

    Hope this helps.

    -Ari

  • Sushma

    Thanks Ari - that works perfectly!!
  • pressing arrow keys as hot-keys changes control focus