Recent

Author Topic: TEdit alternative (because of OnChange)  (Read 512 times)

dseligo

  • Hero Member
  • *****
  • Posts: 866
TEdit alternative (because of OnChange)
« on: November 17, 2022, 07:06:03 pm »
I am not happy that OnChange event in TEdit is fired when Text property is programmatically changed.

I tried with TComboBox control with Style property set to csSimple and so far it seems to work fine. Is there any drawbacks to using TComboBox as replacement for TEdit like that?

Maybe someone has another suggestion for similar control that doesn't fire OnChange when changed programatically (with standard controls only)?

It would be ideal if there is a property to control this behaviour.

GetMem

  • Hero Member
  • *****
  • Posts: 3916
Re: TEdit alternative (because of OnChange)
« Reply #1 on: November 17, 2022, 07:18:13 pm »
Set the OnChange event to nil before changing the text, something like this;
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Edit1Change(Sender: TObject);
  2. begin
  3.   ShowMessage('on change');
  4. end;
  5.  
  6. procedure TForm1.ChangeText(AEdit: TEdit; AText: String);
  7. begin
  8.   AEdit.OnChange := nil;
  9.   AEdit.Text := AText;
  10.   AEdit.OnChange := @Edit1Change;
  11. end;
  12.  
  13. procedure TForm1.Button1Click(Sender: TObject);
  14. begin
  15.   ChangeText(Edit1, 'test');
  16. end;
  17.  

jamie

  • Hero Member
  • *****
  • Posts: 5045
Re: TEdit alternative (because of OnChange)
« Reply #2 on: November 17, 2022, 07:20:58 pm »
The Edit has a MODIFIED property.

If you first clear this property before manually defining the EDIT control, it will be
set to false when the OnChange Event takes place.

 Before exiting that event, you may want to clear it back to false.

 The MODIFIED property gets set to TRUE when user makes edit changes.

 What I do is clear it using the OnEnter event or just before manually setting the EDIT control.

 The same holds true for MEMO etc

EDIT.

   Apparently just setting it manually clears the MODIFIED flag automatically so you don't need to clear it first when manually defining it but it will stay defined to the last state when you exit the control. This allows you to check the status change of the edit elsewhere.
« Last Edit: November 17, 2022, 07:28:51 pm by jamie »
The only true wisdom is knowing you know nothing

dseligo

  • Hero Member
  • *****
  • Posts: 866
Re: TEdit alternative (because of OnChange)
« Reply #3 on: November 17, 2022, 09:46:51 pm »
Set the OnChange event to nil before changing the text, something like this;

I used to do it like this, but I don't like it, that's why I am looking for an alternative.

dseligo

  • Hero Member
  • *****
  • Posts: 866
Re: TEdit alternative (because of OnChange)
« Reply #4 on: November 17, 2022, 09:51:55 pm »
The Edit has a MODIFIED property.

If you first clear this property before manually defining the EDIT control, it will be
set to false when the OnChange Event takes place.

 Before exiting that event, you may want to clear it back to false.

 The MODIFIED property gets set to TRUE when user makes edit changes.

 What I do is clear it using the OnEnter event or just before manually setting the EDIT control.

 The same holds true for MEMO etc

EDIT.

   Apparently just setting it manually clears the MODIFIED flag automatically so you don't need to clear it first when manually defining it but it will stay defined to the last state when you exit the control. This allows you to check the status change of the edit elsewhere.

Is this clearing of Modified property necessary?
I tried this with two edits (both set to the same method) and it seems to work:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Edit1Change(Sender: TObject);
  2. begin
  3.   If (Sender is TEdit) and not (Sender as TEdit).Modified then
  4.     Exit;
  5.  
  6.   If Sender = Edit1 then
  7.     Edit2.Text := IntToStr(StrToInt(Edit1.Text) + 1)
  8.   else
  9.     Edit1.Text := IntToStr(StrToInt(Edit2.Text) + 1)
  10. end;

So only thing I do is check Modified property first and exit if it's not true. I didn't do anything else (i.e. I didn't clear or set Modified property anywhere).
Is there any gotchas in this approach?

jamie

  • Hero Member
  • *****
  • Posts: 5045
Re: TEdit alternative (because of OnChange)
« Reply #5 on: November 17, 2022, 10:21:04 pm »
It's not needed however it will remember the last state the control was in so when you leave the control it will remain as it was.

 Manually setting the content clears this flag.
 
 In your example all you need to do is TEDIT(SENDER).Modified when it comes in.
 If you need to know more details which edit it is, then you can compare the SENDER with a known value at compile time name.

 if it works for you then are all set, it's just nice to know about how it works.

 You need to remember that if you don't manually set the content and you come back to it or leave it again, much like if you were tabbing around, the control will still retain that state. Something to remember.


  I normally clear it in the OnChange event once I do what I need with it if the user has done something.

« Last Edit: November 17, 2022, 10:26:20 pm by jamie »
The only true wisdom is knowing you know nothing

dseligo

  • Hero Member
  • *****
  • Posts: 866
Re: TEdit alternative (because of OnChange)
« Reply #6 on: November 17, 2022, 11:05:14 pm »
OK, thanks.

I'll add code to clear Modified property at the end, like you suggested:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Edit1Change(Sender: TObject);
  2. begin
  3.   If (Sender is TEdit) and not TEdit(Sender).Modified then
  4.     Exit;
  5.  
  6.   If Sender = Edit1 then
  7.     Edit2.Text := IntToStr(StrToInt(Edit1.Text) + 1)
  8.   else
  9.     Edit1.Text := IntToStr(StrToInt(Edit2.Text) + 1);
  10.  
  11.   TEdit(Sender).Modified := False;
  12. end;

Username

  • New Member
  • *
  • Posts: 28
Re: TEdit alternative (because of OnChange)
« Reply #7 on: November 26, 2022, 04:59:28 am »
Hi, dseligo,
I noticed your code, and thought I'd suggest you might use a SpinEditEx instead of the TEdit control, given that it looks like you're only doing numbers there.

You can set the UpDown Visible property to FALSE and then it will look just like a TEdit, but simpler to handle numbers.

The OnChange will be called with programmatic changes though, just like the TEdit.
« Last Edit: November 26, 2022, 05:14:00 am by Username »

Thaddy

  • Hero Member
  • *****
  • Posts: 12553
Re: TEdit alternative (because of OnChange)
« Reply #8 on: November 26, 2022, 10:15:51 am »
The clearing of modified is indeed necessary as well as the manual control over it, just because you would not be able to properly save modified files or at least present a dialog that asks to save modifications. All proper edits and editors work like that. Do not re-invent wheels and turn them into hexagons. The ride will be bumpy..
Writing code in an overly complex way is usually merely a complete misunderstanding of the goal you are trying to achieve.

 

TinyPortal © 2005-2018