delphicheckboxevent-handlingdelphi-xe3data-aware

How to make TDBCheckBox update its DataField immediately after click?


I have a form with several controls where the first one is a TDBCheckBox that is bound to DataField := 'enabled'.

When the checkbox is clicked I want all the remaining controls to be enabled / disabled.

procedure TMyAdapter.DataSourceDataChange(Sender: TObject; Field: TField);
var
  Enabled: Boolean;
begin
  Enabled := FModel.DataSet['enabled'].AsBoolean;
  FView.Label1.Enabled   := Enabled;
  FView.DBEdit1.Enabled  := Enabled;
  FView.Label2.Enabled   := Enabled;
  FView.DBEdit2.Enabled  := Enabled;
  FView.Label3.Enabled   := Enabled;
  FView.DBEdit3.Enabled  := Enabled;
  FView.Label4.Enabled   := Enabled;
  FView.DBEdit4.Enabled  := Enabled;
end;

This only works when the focus leaves the checkbox or when the dataset is scrolled (I have a navigator on this form as well).

Is there a way to make the checkbox update its datafield immediately?

Or is there even a better alternative to achieve what I have described?


Solution

  • A couple of problems with using the DataChange event to do things like this are that

    Ime, it's best to use a standardised way of dealing with these sorts of problems and the one I use is to write a custom message handler that does the work you want, and to call it using PostMessage from your DBCheckBox1Click handler, as shown below:

    const
          WM_AutoPost = WM_User + 1;
    type
      TForm1 = class(TForm)
        [...]
      private
        procedure DoAutoPost;
        procedure WMAutoPost(var Msg : TMessage); message WM_Autopost;
      [...]
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    [...]
    
    procedure TForm1.DBCheckBox1Click(Sender: TObject);
    begin
      PostMessage(Self.Handle, WM_AutoPost, 0, 0);
    end;
    
    procedure TForm1.DoAutoPost;
    begin
      if CDS1.State in [dsEdit, dsInsert] then begin
        CDS1.Post;
        //  Update other controls here
      end;
    end;
    
    procedure TForm1.WMAutoPost(var Msg: TMessage);
    begin
      DoAutoPost;
    end;