Forcing My Hand - One Hand That Is
So, you’re building a Pocket PC application against the .NET Compact Framework 1.0 and you want to support one hand operation. You have a ComboBox nestled between two other controls. Once you get focus on the ComboBox, how do you allow the user to get off the ComboBox control? D-Pad navigation would be the way to go. However, the Up AND Left keys change the control’s selection to the previous value in the list, and the Down AND Right keys change the selection to the next value in the list.
It would be cool if the Up and Down keys let you move to the Previous/Next control (like on the Smartphone). So, you think you can capture the KeyDown event, handle the event, and you are good to go… something like this would seem to do the trick:
       public Control GetNextControl(Control ctl, bool forward)
       {
           int curIndex = this.Controls.IndexOf(ctl);
           if (forward)
           {
               if (curIndex < this.Controls.Count)
                   curIndex++;
               else
                   curIndex = 0;
           }
           else
           {
               if (curIndex > 0)
                   curIndex- -;
               else
                   curIndex = this.Controls.Count - 1;
           }
           return this.Controls[curIndex];
       }
       private void comboBox_KeyDown(object sender, KeyEventArgs e)
       {
           if (e.KeyCode == Keys.Up)
           {
               // Move to the previous control and handle the event
               GetNextControl(this, false).Focus();
               e.Handled = true;
           }
           else if (e.KeyCode == Keys.Down)
           {
               // Move to the next control and handle the event
               GetNextControl(this, true).Focus();
               e.Handled = true;
           }
       }
It doesn’t work… the focus changes to the proper control which is cool, but the combobox’s selected value still changes. At this point you might get a bit annoyed and after a cup of coffee and chilling out, you end up with something like this:
       // Keep track of the previous selected index
       int previousIndex = -1;
       private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
       {
           if (previousIndex != -1)
           {
               ((ComboBox)sender).SelectedIndex = previousIndex;
               // Reset this to -1 so we only fire this logic when Up or Down is pressed
               previousIndex = -1;
           }
       }
       private void comboBox_KeyDown(object sender, KeyEventArgs e)
       {
           if (e.KeyCode == Keys.Up)
           {
               GetNextControl(this, false).Focus();
               // e.Handled = true; THIS DOES NOT APPEAR TO FUNCTION PROPERLY
               previousIndex = ((ComboBox)sender).SelectedIndex;
           }
           else if (e.KeyCode == Keys.Down)
           {
               GetNextControl(this, true).Focus();
               // e.Handled = true; THIS DOES NOT APPEAR TO FUNCTION PROPERLY
               previousIndex = ((ComboBox)sender).SelectedIndex;
           }
       }
       private void comboBox_GotFocus(object sender, EventArgs e)
       {
           // If the behavior is as we expect (ie, Smartphone) make sure that works too!
           previousIndex = -1;
       }
It’s a bit of a kludge, but it worked for me. Hope this helps.
-kevin