2

我有一个带有多个控件的表单,其中第一个TDBCheckBox是绑定到DataField := 'enabled'.

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

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;

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

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

还是有更好的选择来实现我所描述的?

4

3 回答 3

3

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

于 2015-06-21T10:54:49.100 回答
2

使用 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;
于 2015-06-21T11:59:06.410 回答
1

这是我根据 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;
于 2015-06-22T07:18:35.303 回答