Jump to content
Ruud

problem with ComboBox

Recommended Posts

procedure TForm1.Form_Create (Sender: TObject);
begin
  ComboBox1.ItemIndex := -1;
  ComboBox1.Text      := 'ComboBox Test';

  ComboBox1.Items.Clear;
  ComboBox1.Items.Add ('Test 0');
  ComboBox1.Items.Add ('Test 1');
  (...)
end

procedure TForm1.ComboBox1_Change (Sender: TObject);
begin
  case ComboBox1.ItemIndex  of
    0 : ShowMessage ('Combobox1_Change | ItemIndex = 0');
    1 : ShowMessage ('Combobox1_Change | ItemIndex = 1');
  end;
end;

procedure TForm1.Panel1_Click (Sender: TObject);
begin
  ComboBox1.ItemIndex := 1;
end;

After starting the program , the ComboBox1 text is 'ComboBox Test' .

 

When I select 'Test 0' in ComboBox1 , the ComboBox1 text is changed into 'Test 0' , and the correct message box (with message 'Combobox1_Change - ItemIndex = 0') is displayed .

 

But when I click on Panel1 , only the ComboBox1 text is changed into 'Test 1' .
There's no message box !

 

What extra statement must be added to the Panel1_Click procedure ?

Share this post


Link to post
3 hours ago, Ruud said:

But when I click on Panel1 , only the ComboBox1 text is changed into 'Test 1' .
There's no message box !

The documentation for TComboBox.OnChange has this note:

Quote
Note: OnChange only occurs in response to user actions. Changing the Text property programmatically does not trigger an OnChange event.

 

3 hours ago, Ruud said:

What extra statement must be added to the Panel1_Click procedure ?

I'd extract the case statement from ComboBox1_Change to a separate procedure and call the new procedure from both ComboBox1_Change and Panel1_Click.

Share this post


Link to post
5 hours ago, corneliusdavid said:

The documentation for TComboBox.OnChange has this note:

Quote
Note: OnChange only occurs in response to user actions. Changing the Text property programmatically does not trigger an OnChange event.

 

Thanks for your response , but I did not change the Text property in the Panel1_Click .

 

I changed the ComboBox1.ItemIndex property .

Shouldn't that be enough to trigger the ComboBox1_Change ?

Share this post


Link to post
23 minutes ago, Ruud said:

Thanks for your response , but I did not change the Text property in the Panel1_Click .

 

I changed the ComboBox1.ItemIndex property .

Shouldn't that be enough to trigger the ComboBox1_Change ?

No, since it is not a user-triggered change from the combobox's view.

Share this post


Link to post
4 hours ago, Ruud said:

I did not change the Text property in the Panel1_Click .

 

I changed the ComboBox1.ItemIndex property .

You're right--sorry; still, like PeterBelow said, it's not a user-triggered change.

Share this post


Link to post
4 hours ago, PeterBelow said:

No, since it is not a user-triggered change from the combobox's view.

 

10 minutes ago, corneliusdavid said:

You're right--sorry; still, like PeterBelow said, it's not a user-triggered change.

User-triggered ?

But clicking on Panel1 did do something with ComboBox1 : visibly it changed the Text property from 'Test 0' to 'Test 1' (most likely because ItemIndex was changed from 0 to 1) .
That information is only available in ComboBox1 .

 

It looks like ComboBox1_Change is partially executed .
I don't know why  the case statement isn't executed as well .

Share this post


Link to post
11 minutes ago, Ruud said:

User-triggered ?

The user did not interact with the ComboBox directly, they interacted with the Panel instead. The Panel's OnClick event invoked an API call to the ComboBox (the ItemIndex setter sends a CB_SETCURSEL message to the ComboBox), thus the text change is not a user-triggered action from the ComboBox's perspective, it is an application-triggered action.  The ComboBox's OnChange event is fired in reply to a CBN_EDITCHANGE notification from the ComboBox, and CB_SETCURSEL does not trigger a CBN_EDITCHANGE notification.

Share this post


Link to post
Posted (edited)
1 hour ago, Remy Lebeau said:

The user did not interact with the ComboBox directly, they interacted with the Panel instead. The Panel's OnClick event invoked an API call to the ComboBox (the ItemIndex setter sends a CB_SETCURSEL message to the ComboBox), thus the text change is not a user-triggered action from the ComboBox's perspective, it is an application-triggered action.  The ComboBox's OnChange event is fired in reply to a CBN_EDITCHANGE notification from the ComboBox, and CB_SETCURSEL does not trigger a CBN_EDITCHANGE notification.

OK , thank you all , I'm convinced , it's not a user-triggered change .

:classic_smile:

 

So , because Delphi won't execute the ComboBox1_Change event handler for me voluntarily , I'll force Delphi to do so !

:classic_biggrin:

procedure TForm1.Panel1_Click (Sender: TObject);
begin
  ComboBox1.ItemIndex := 1;
  ComboBox1_Change (Sender);  {  <<====  }
end;

Problem solved !

 

Edited by Ruud

Share this post


Link to post
type
  TComboboxHelper = class helper for TCombobox
  public
    procedure DoOnChange;
  end;
  
implementation

{ TComboboxHelper }
procedure TComboboxHelper.DoOnChange;
begin
  if Assigned(OnChange) then
    Onchange(Self);
end;

I would put this to a helper to save me problems when I change the procedure on combobox OnChange. 

procedure TForm1.Panel1_Click (Sender: TObject);
begin
  ComboBox1.ItemIndex := 1;
  ComboBox1.DoOnChange;  
end;

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×