Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 453
  • Last Modified:

Why does my delphi application run through EditValueChange procedures on FormShow???

I stepped through line by line and realized that on FormShow, my apps run through EditValueChange procedures... right when the dataset is opened. Is there a way to code it so that it doesnt do that?
0
Bianca
Asked:
Bianca
1 Solution
 
Geert GruwezOracle dbaCommented:
do you debug with 2 monitors ?
1 monitor contains your app
the second monitor contains delphi debugging

if not, and delphi overlaps the app form, then a redraw takes place (or a formshow) to visualize the form

make sure your debugging doesn't cause form refreshes

if you don't what that happening ... don't put code in formshow
0
 
Ephraim WangoyaCommented:

When the dataset is opened, the value of your edit is modified by the value of the filed in the dataset so it naturally triggers the ValueChangeEvent

You overcome this by setting a variable which indicates that the data is still being loaded

Add a private member eg

TForm1 = class(TForm)
......
private
   FDataLoading: Boolean;
....
end;

in the formshow procedure, set the dataloading to true

procedure TForm1.FormShow(Sender: TObject);
begin
  FDataLoading := True;
  try
    //initialize your stuff
   Dataset.Active := True;
  finally
    FDataLoading := False;
  end;
end;

in the EditValueChange, check for dataloading and exit
procedure TForm1.EditValueChange(Sender: TObject);
begin
  if FDataLoading then
    Exit;

  //do your other stuff
end;


0
 
SleekProductionsCommented:
Depending on the whole application one may also create all the DB Controls, connect them to Datasets and *then* set the Dataset.Active = true. Depending on DAL and visual controls that might even look better/be faster. An alternative is to activate the dataset *before* assigning it to the DB controls.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
developmentguruCommented:
You will need to setup a background variable like:

  fInternalMod : boolean;

In your OnChange routine :

  if not fInternalMod then
    begin

      //your code here

    end;

When opening your dataset (or wherever you want to make changes without triggering the OnChange events)

  fInternalMod := true;
  try
    Dataset.Open;  //opening the dataset will call the OnChange but will not use the code...
    //your code here
  finally
    fInternalMod := false;
  end;

The alternative to this would be to disconnect the on change of all concerned controls before opening the dataset and reconnecting them all after.  This was should be a lot simpler and easier to maintain.  

If your case is this simple, this will work fine.  I have run into more complicated cases where the solution, while the same, would need to be more robust.  Let me know if you need more.
0
 
developmentguruCommented:
My last comment was almost the same as 34920665.  The more robust method would work like this.


protected
  fChangeBlockCount : integer;
  procedure DisableChangeEvents;
  procedure EnableChangeEvents;
  ...

procedure Form1.DisableChangeEvents;
begin
  inc(fChangeBlockCount);
end;


procedure Form1.EnableChangeEvents;
begin
  if fChangeBlockCount > 0 then
    dec(fChangeBlockCount);
end;

procedure Form1.Edit1OnChange(Sender : TObject);
begin
  if fChangeBlockCount = 0 then
    begin
      //Your code here.
    end;
end;

procedure TForm1.OpenDataset;
begin
  DisableChangeEvents;
  try
    //open datasets... your code here
  finally
    EnableChangeEvents;
  end;
end;

Open in new window

0
 
Geert GruwezOracle dbaCommented:
even better ... remote debugging

:)
0
 
developmentguruCommented:
One final note... you can also modify the last type I showed you to work when you need multiple sources to be able to stop access to any resource... making sure to update that resource once when they are all finished.  To do this you would modify the EnableChangeEvents like this:
procedure Form1.EnableChangeEvents;
begin
  if fChangeBlockCount > 0 then
    begin
      dec(fChangeBlockCount);
      if fChangeBlockCount = 0 then
        //Call your update (or on change) procedure(s) here.  only happens when all are finally unblocked.
    end;
end;

Open in new window

0
 
RezaSadighCommented:
Hi my friend,
Write this statement for the first line of the FormShow
  Edit1.OnChange:= nil;  // assume that your editor name is Edit1

and after opening DataSet write this
  Edit1.OnChange:= Edit1OnChange

by this trick you can suppress the event trough opening dataset and activate it again.
best regards
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now