Recent

Author Topic: OnChange not fired by code changes of value. Alternatives?  (Read 27549 times)

Elmug

  • Hero Member
  • *****
  • Posts: 849
OnChange not fired by code changes of value. Alternatives?
« on: July 24, 2011, 05:49:02 am »
I want to have two read-only SpinFloatEdit components. The first to receive values by code (no problem there). The second one, however, I want to show the value of the first one with a different format, though.

OnChange works if on the first I change to readonly=false. And when I make changes, the second display shows correctly.

However, as said, the first display is not meant for manual entry, but for entry by program code.

Is there no such thing as OnChange that works also when data goes into Value by code?

Is the alternative, then, only to do it by program code?

Thanks!

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #1 on: July 24, 2011, 12:51:18 pm »
Quote
Is the alternative, then, only to do it by program code?
I guess so, when a control is readonly, it isn't supposed to process anything regarding to input. You could trigger the OnChange manually however.

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #2 on: July 24, 2011, 01:20:22 pm »
I guess so, when a control is readonly, it isn't supposed to process anything regarding to input.

I disagree.
The OnChange should be triggered whenever the content changes.
At least in Delphi (D3 TSpinEdit) it does, and also controls like TEdit fire OnChange if Text is changed by code, while control is read-only.

ATM it seems that setting Value by code does not trigger OnChange for TFloatSpinEdit, regardless of the the value of ReadOnly.

I would consider it a bug and I would suggest reporting it in the bugtracker.

Debugging TCustomFloatSpinEdit.TextChanged reveals (on Windows that is) that


Code: [Select]
procedure TCustomFloatSpinEdit.TextChanged;
var
  PrevValue: Double;
begin
  PrevValue := FValue;
  FValueChanged := True;
  if Value <> PrevValue then

  //the above always evaluates to False, so inherited is never called and hence OnChange ir never fired.

  begin
    FValueEmpty := False;
    inherited;
  end;
end;

Bart

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #3 on: July 24, 2011, 03:43:34 pm »
AFAICS., OnChange event handler of TFloatSpinEdit is triggered when it is on ReadOnly state.

Lazarus 0.9.30 r29749 FPC 2.4.2 i386-win32-win32/win64

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #4 on: July 24, 2011, 04:26:02 pm »
Here is what happens:

Code: [Select]
  ASpinEdit.Value := NewValue
 
  this will call  UpdateFloatSpinEditControl()
  which will do
 
  lWindowInfo^.spinValue := AFloatSpinEdit.Value;

  Finally FValue is set to NewValue

  then in TextChanged we do:

  PrevValue := FValue;
  //PrevValue now holds NewValue

  if Value <> PrevValue then

  this calls GetValue which ultimately does

  Result := GetWin32WindowInfo(ACustomFloatSpinEdit.Handle)^.spinValue;

  and this value we have set to NewValue in SetValue !!

  so Value will alway be equal to FValue at this point

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #5 on: July 24, 2011, 04:58:24 pm »
This also happens on Linux/GTK2 (probably on all widgetsets?).

Reported in the bugtracker: http://bugs.freepascal.org/view.php?id=19801

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #6 on: July 25, 2011, 12:49:52 pm »
I alos osted a possible fix for this issue.
Now it's waiting for the admins to approve and apply, or dismiss..

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #7 on: July 26, 2011, 11:52:20 am »
Fixed in revision 31803.

Elmug

  • Hero Member
  • *****
  • Posts: 849
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #8 on: July 27, 2011, 06:12:00 pm »
Fixed in revision 31803.

Thanks a lot Bart.

Now, if already possible, how do I install this fix on my Windows XP setup?

Thanks! :(

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #9 on: July 28, 2011, 10:55:38 am »
Several possibilities:

Bart

Elmug

  • Hero Member
  • *****
  • Posts: 849
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #10 on: July 28, 2011, 11:07:36 am »
Thanks Bart.

OnChange wouldn't that basically be something like before a change is allowed, the existing value is copied, and then compared to see if there was change upon exit and  if different, the OnChange procedure is fired, regardless of the readonly being true or false, by code or by manual entry into the value?

Is that the way it will be with the update?

Thanks.

Elmug

  • Hero Member
  • *****
  • Posts: 849
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #11 on: July 28, 2011, 11:35:24 am »
Hi, I also would appreciate knowing if "On Change" of a component applies to a change in ANY of its properties?

Or does each property have its own OnChange event?

Thanks!

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #12 on: July 28, 2011, 01:28:57 pm »
TCustomEdit descendants have a procedure TextChanged that is called when the OS sends a notification that the text in the control has changed.

In TextChanged eventually Change is called.
Change then calls the OnChange event handler (if one is assigned).

So, if text is changed (by user input, or by code) OnChange event will be fired: at that point Text constains the new text. So unless you keep track of the old text yourself, you do not know what the text before the OnChange is.

The Borland guys better had called it OnChanged  8)

Bart

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #13 on: July 28, 2011, 01:40:31 pm »
I documented it with the following changes to our docs:

       <element name="TFloatSpinEdit.OnChange">
         <short>The OnChange event is fired when spin edit value has changed.</short>
+        <descr>This OnChange event is based on <var>TCustomEdit.OnChange</var>, so it is fired both on changes made by the user and also for changes made by code. A change is defined as a modification which will cause the text displayed on the screen by the control to change. This corresponds to a change in the property Value of the control. The event is called after the change takes place, so the Value property will contain the new value.</descr>
+        <seealso>
+          <link id="#LCL.StdCtrls.TCustomEdit.OnChange">TCustomEdit.OnChange</link>
+          <link id="#LCL.Spin.TSpinEdit.OnChange">TSpinEdit.OnChange</link>
+        </seealso>
       </element>

This will eventually make it's way to the online docs in the next update.

Hi, I also would appreciate knowing if "On Change" of a component applies to a change in ANY of its properties?
Or does each property have its own OnChange event?

As the documentation above says, it applyes to the properties Text and Value.

For left, top, width and/or height changes there is OnResize.
« Last Edit: July 28, 2011, 01:42:38 pm by felipemdc »

Elmug

  • Hero Member
  • *****
  • Posts: 849
Re: OnChange not fired by code changes of value. Alternatives?
« Reply #14 on: September 05, 2011, 10:40:30 am »
Thanks Felipe. Good job.

 

TinyPortal © 2005-2018