2

I have a TComboBox on a form. Its Style property is set to csDropDownList. If I open the dropdown and select an option with my mouse or keyboard and hit ENTER, the dropdown box closes and the ItemIndex property is changed before the KeyPress event handler is fired. If I hit TAB, the dropdown doesn't disappear until after the KeyPress event handler has fired and focus has moved off the control, and the ItemIndex doesn't get updated; it reverts back to whatever had been selected before I opened the list.

If I want TAB to update ItemIndex to whatever's currently selected in the dropdown list, how would I implement it?

Mason Wheeler
  • 77,748
  • 42
  • 247
  • 453
  • I find it amusing that you ask questions with Steven and Francois as typically the most common answers, especially since Steven sits behind you. – Jim McKeeth Jun 13 '09 at 04:03
  • 1
    If you're using the keyboard to select a value in a combobox, you shoudl consider using the keyboard only, and not open the combobox drop down. By hitting up and down arrows, you can change the selected item (and ItemIndex property value) directly, and also tab will work normally. Agreed, you don't have the oversight over the list of items in the dropdown, but if there are a lot of items, an interface architect should get wondering if a combobox is the right control for the job. – Stijn Sanders Jun 14 '09 at 09:03
  • 1
    Agree with Stijn, and with skamradt, and in line with those comments I suggest that you exercise considerable reluctance to change the default behaviour of a common interface element (unless that default behaviour is demonstrably non-standard). – Argalatyr Jun 14 '09 at 17:49

4 Answers4

3

Set the Form's KeyPreview property to True.

In the ComboBox OnKeyDown event:

procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = VK_TAB) then
  begin
    Key := VK_RETURN;
    Perform(WM_NEXTDLGCTL,0,0);
  end;
end;

This emulates the return key and then moves focus to the next control.

J__
  • 3,527
  • 1
  • 21
  • 29
  • Just for completeness, if you wish to also use Shift & Tab to go back: if ssShift in shift then Perform(WM_NEXTDLGCTL,1,0) else Perform(WM_NEXTDLGCTL,0,0); – Mark Robinson Aug 08 '14 at 09:29
0

When you retrieve your index use this instead of the classical ComboBox->ItemIndex

ComboBox->Items->IndexOf(ComboBox->Text)
0

I believe this is the default behavior, and to change it you might need to subclass the control (or even a class helper), intercept the windows message for the keystroke, then if its a tab send a return to the control and handle the tab yourself.

skamradt
  • 14,916
  • 2
  • 33
  • 49
0

You should try to trap TAB earlier in the KeyUp event or maybe even earlier in the KeyDown.

Francesca
  • 21,156
  • 3
  • 46
  • 87