如何在点击后立即让TDBCheckBox更新其DataField?

时间:2015-06-21 10:28:50

标签: delphi checkbox event-handling delphi-xe3 data-aware

我有一个包含多个控件的表单,其中第一个是绑定到TDBCheckBox的{​​{1}}。

单击该复选框时,我希望启用/禁用所有其余控件。

DataField := 'enabled'

这仅在焦点离开复选框或滚动数据集时才有效(我在此表单上也有导航器)。

有没有办法让复选框立即更新其数据字段?

或者是否有更好的替代方案来实现我所描述的目标?

3 个答案:

答案 0 :(得分:3)

您可以调用DataSet UpdateRecord方法使任何链接的DB控件将其数据存储到基础字段中。

答案 1 :(得分:1)

使用DataChange事件执行此类操作的几个问题是

  • 比你实际需要的频率要高得多,对点击的DBCheckBox作出反应

  • 对数据集执行.Post会改变其状态,这在事件中通常是一个坏主意,事件本身可以通过更改数据集状态来触发。

Ime,最好使用标准化的方法来处理这些类型的问题,我使用的是编写一个自定义的消息处理程序来完成你想要的工作,并使用来自DBCheckBox1Click处理程序的PostMessage来调用它,如如下所示:

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;

答案 2 :(得分:0)

这是我根据Uwe和MartynA的答案输入构建的解决方案:

procedure TMyAdapter.EnabledClick(Sender: TObject);
begin
  PostMessage(FView.Handle, WM_ENABLED_CLICKED, 0, 0);
end;

procedure TMyAdapter.WMEnabledClicked(var Msg: TMessage);
var
  DataSet: TDataSet;
begin
  DataSet := FView.EnabledCheckBox.Field.DataSet;
  if not (DataSet.State in [dsInsert, dsEdit]) then 
    DataSet.Edit;
  DataSet.UpdateRecord;
end;

procedure TMyAdapter.DataSourceDataChange(Sender: TObject; Field: TField);
var
  Enabled: Boolean;
begin
  if (Field = nil) or (Field = FView.EnabledCheckBox.Field) then
  begin
    Enabled := FView.EnabledCheckBox.Field.AsBoolean;
    FView.Label1.Enabled   := Enabled;
    FView.DBEdit1.Enabled  := Enabled;
    // etc.
  end;
end;