【发布时间】:2014-09-01 08:51:13
【问题描述】:
我几乎完成了一些代码来解决去年这个未回答的问题:
Refresh Nested DataSet with poFetchDetailsOnDemand
公认的观点是,如果不关闭并重新打开主 CDS,就不可能从服务器刷新嵌套的详细 CDS,但显然这会产生不成比例的网络流量,仅刷新单个主行及其详细信息行。
我想到了一种直接刷新细节 CDS 的方法 从服务器,它几乎工作。我下面的代码基本上是通过暂时刷新细节 将过滤器应用于主 ADO 查询以将其过滤到当前主行,并且在该过滤器有效时, 通过对其应用类似的过滤器然后调用其 Refresh 方法来刷新主 CDS。这是由主 CDS AfterScroll 事件触发的。
只有一个 teeny 问题:在我的表单以及 4 个数据集和随附的网格上,我在表单上有一个刷新按钮,它调用了我的 RefreshcdsMasterAndDetails 也在 cdsMasterAfterScroll 中调用。如果我使用其网格在主 CDS 中移动,我的代码一切正常,并且详细 CDS 行以及 AdoQuery 详细信息 中的那些立即正确更新,但如果我通过单击刷新按钮触发它,CDS 详细信息行仅在我单击“刷新”按钮时每秒钟更新一次。
我的问题是:为什么当我的代码从按钮单击而不是从 AfterScroll 事件触发时,它的效果应该有什么不同,因为它可靠地完成了从 AfterScroll 事件调用它应该做的事情但只有在通过按钮点击触发时才每隔一次?
//Obviously MasterPKName below is a const and DoingRefresh is a boolean
// flag on the form
procedure TForm1.cdsMasterRowRefresh(MasterPK : Integer);
begin
if DoingRefresh then Exit;
DoingRefresh := True;
try
cdsMaster.Prior;
cdsMaster.Next;
cdsMaster.Filter := MasterPKName + ' = ' + IntToStr(MasterPK);
cdsMaster.Filtered := True;
cdsMaster.Refresh;
cdsMaster.Filtered := False;
cdsMaster.Locate(MasterPKName, MasterPK, []);
finally
DoingRefresh := False;
end;
end;
procedure TForm1.qMasterRowRefresh(MasterPK : Integer);
begin
qMaster.Filter := MasterPKName + ' = ' + IntToStr(MasterPK);
qMaster.Filtered := True;
qMaster.Refresh;
cdsMasterRowRefresh(MasterPK);
qMaster.Filtered := False;
qMaster.Locate(MasterPKName, MasterPK, []);
end;
procedure TForm1.RefreshcdsMasterAndDetails;
var
MasterPK : Integer;
begin
MasterPK := cdsMaster.FieldByName(MasterPKName).AsInteger;
cdsDetail.DisableControls;
cdsMaster.DisableControls;
qDetail.DisableControls;
qMaster.DisableControls;
try
qMasterRowRefresh(MasterPK);
finally
qMaster.EnableControls;
qDetail.EnableControls;
cdsMaster.EnableControls;
cdsDetail.EnableControls;
end;
end;
procedure TForm1.cdsMasterAfterScroll(DataSet: TDataSet);
begin
RefreshcdsMasterAndDetails;
end;
【问题讨论】:
-
好点。我已经被这个问题包裹了一天多,以至于我设法把这个问题排除在外!我马上编辑它。
-
好吧,我相信在 CDS 中,您可以拥有多个密钥字段,但您对我的问题的解决方案将是不完整的。但是,嘿,+1 这是解决问题的一个棘手的想法......
-
谢谢。由于您的意思是多字段键或其他原因而导致不完整?由于我在服务器详细信息表中遇到了类似的问题,我的代码与我发布的内容有所不同。
-
因为多字段,但没关系,因为这很容易改变。反正你为什么选择
OnAfterScroll? -
基本上是因为 IME 是最可靠的事件,可以识别当前主行已更改的事实,因此 cdsDetail 需要获取一组不同的行。我曾在许多情况下使用它,由于各种原因,依靠 VCL 获取正确主记录的详细信息是不切实际的。
标签: delphi ado master-detail tclientdataset