Delphi 如何使TDBCheckBox在单击后立即更新其数据字段?
我有一个带有多个控件的表单,其中第一个控件是绑定到Delphi 如何使TDBCheckBox在单击后立即更新其数据字段?,delphi,checkbox,event-handling,delphi-xe3,data-aware,Delphi,Checkbox,Event Handling,Delphi Xe3,Data Aware,我有一个带有多个控件的表单,其中第一个控件是绑定到DataField:=“enabled”的TDBCheckBox 单击复选框时,我希望启用/禁用所有剩余控件 procedure TMyAdapter.DataSourceDataChange(Sender: TObject; Field: TField); var Enabled: Boolean; begin Enabled := FModel.DataSet['enabled'].AsBoolean; FView.Label1.
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将改变其状态,这在事件中通常是一个坏主意,而事件本身可能由数据集状态的更改触发
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;
您的解决方案仍然存在一个问题:因为您是根据窗口消息进行更新的,所以在滚动数据集时不会触发该消息。很高兴您找到了工作,尽管我不确定我是否遵循您的评论“滚动数据集时不会触发该消息”由于WM_AutoPost消息是在单击DBCheckBox后立即发布的,所以在数据集滚动时应该已经发布了更改?如果不是,那么我个人会从数据集的BeforeColl事件调用我的DoAutoPost。例如,当表单首先加载时,数据集已经包含enabled=False。当复选框的选中状态更改时,仅更新启用状态是不够的。这仍然留下了何时调用
UpdateRecord
的问题。我现在把这个和MartynA的答案结合起来,看看我自己的答案。