Look at attached demo which contains only a combobox (plus a memo for registering the OnEditingDone events and a radiogroup for easy changing the Style of the Combobox): It fires the OnEditingDone event twice too if an item is selected from the dropdown with the ENTER key.
I tried this demo and learned something new about ComboBoxes. And now I understand, why the Event is fired twice.
But I think, it's a bug, that 1 exit (via ENTER) fires an event twice. If the OnEditingDone-Event is already fired in procedure TCustomComboBox.CloseUp, then the 2nd event via ENTER in my opinion is a bug.
@wp: do you agree?
Why is it harmful for your code when then OnEditingDone event fires twice?
This event reads data from a SQL-DB, which can need some seconds.
The demo of wp inspired me to a solution, which works well:
- set a flag in the TComboBox.OnEnter-Event
- excecute the actions in TComboBox.OnEditingDone-Event only, if the flag is set
- at the end of OnEditingDone-Event set the focus to another control, which forces the user to "enter" the ComboBox again, so that a new OnEnter-Event is fired
Now the OnEditingDone-Event is always fired twice (because of 'stealing' the focus), but this is now harmless because of the flag.
This is my code (project is attached):
unit Unit1;
{$mode objfpc}{$H+}
{$apptype console} {neccessary for writeln}
interface
uses
Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
ComboBox1: TComboBox;
ListBox1: TListBox;
procedure ComboBox1Enter(Sender: TObject);
procedure ComboBox1EditingDone(Sender: TObject);
private
public
end;
var Form1: TForm1;
implementation
{$R *.lfm}
const enable_event: boolean = true;
procedure TForm1.ComboBox1Enter(Sender: TObject);
begin
writeln('OnEnter');
enable_event:=true; // enable the EditingDone-Event 1x
end;
procedure TForm1.ComboBox1EditingDone(Sender: TObject);
const nr: integer = 1;
var ee: boolean;
begin
writeln('OnEditingDone', nr, ' enable=', enable_event);
inc(nr);
ee:=enable_event; // memorize permission
enable_event:=false; // reset permission
if not ee then exit; // exit if no permission
ListBox1.SetFocus; // steal the focus from the ComboBox
end;
end.