我有一个带有多个控件的窗体,其中第一个控件是绑定到DataField := 'enabled'
的TDBCheckBox
。
单击复选框时,我希望启用/禁用所有剩余的控件。
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;
只有当焦点离开复选框或滚动数据集时(我在这个表单上也有一个导航器),这才有效。
有没有办法让复选框立即更新其数据字段?
或者还有更好的选择来实现我所描述的吗?
您可以调用DataSets UpdateRecord
方法,使任何链接的DB控件将其数据存储到底层字段中。
使用DataChange事件执行类似操作的几个问题是
-
它的调用频率比您实际需要的要高得多,以对单击DBCheckBox和做出反应
-
对数据集执行.Post会更改其状态,这在事件内部通常是个坏主意,因为事件本身可能会由数据集状态的更改触发。
我认为,最好使用标准化的方法来处理这类问题,我使用的方法是编写一个自定义消息处理程序来完成您想要的工作,并使用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;
这是我根据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;