Delphi. How to Disable/Enable controls without triggering controls events

controls, dataset, delphi

Solution

Building on Guillem's post:

Turn off everything:

Traverse each component on the form with the for-loop, shown below, changing the properties to the desired value.

If you want to later revert back to the original property values, then you must save the original value (as OldEvent is used below.)

Edit: The code below shows the key concept being discussed. If components are being added or deleted at run-time, or if you'd like to use the absolutely least amount of memory, then use a dynamic array, and as Pieter suggests, store pointers to the components rather than indexing to them.

  const
    MAX_COMPONENTS_ON_PAGE = 100; // arbitrarily larger than what you'd expect. (Use a dynamic array if this worries you.
  var 
     OldEvent: Array[0.. MAX_COMPONENTS_ON_PAGE - 1] of TNotifyEvent; // save original values here
     i: Integer;
  begin                                 
   for i := 0 to ComponentCount - 1 do 
   begin
     if (Components[i] is TCheckBox)  then 
        begin
          OldEvent[i] := TCheckBox(Components[i]).OnClick; // remember old state  
          TCheckBox(Components[i]).OnClick := nil;
        end
      else if (Components[i] is TEdit) then
         begin
           OldEvent[i] := TEdit(Components[i]).OnClick; // remember old state  
           TEdit(Components[i]).OnClick := nil;          
         end;
    end;

Revert to former values

 for i := 0 to ComponentCount - 1 do 
 begin
   if (Components[i] is TCheckBox)  then
      TCheckBox(Components[i]).OnClick := OldEvent[i]
   else if (Components[i] is TEdit)  then
      TEdit(Components[i]).OnClick := OldEvent[i];
 end;

There may be a way to fold all of the if-statements into one generic test that answers "Does this component have an OnClickEvent" -- but I don't know what it is.

Hopefully someone will constructively criticize my answer (rather than just down voting it.) But, hopefully what I've shown above will be workable.

Problem

I have a DataSet (`TZQuery`), which has several boolean fields, that have TDBCheckBoxes assigned to them. These CheckBoxes have "`OnClick`" events assigned to them and they are triggered whenever I change field values (which are assigned to checkboxes). The problem is that I do not need these events triggerred, during many operations i do with the dataset. I've tried calling `DataSet.DisableControls`, but then events are called right after i call `DataSet.EnableControls`. So my question is - is there a way to disable triggering Data-aware controls events. Edit (bigger picture): If an exception happens while let's say saving data, i have to load the default values (or the values i've had before saving it). Now while loading that data, all these events (TDBCheckBoxes and other data-aware controls) are triggered, which do all sorts of operations which create lag and sometimes even unwanted changes of data, i'm looking for an universal solution of disabling them all for a short period of time.

Original source