- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我几乎已经完成了一些代码来解决去年这个未回答的问题中的问题:
Refresh Nested DataSet with poFetchDetailsOnDemand
公认的观点是,如果不关闭并重新打开主 CDS,就不可能从服务器刷新嵌套的详细 CDS,但显然,仅仅为了刷新单个主行及其详细信息行。
我想到了一个简单的方法来刷新详细CDS来自服务器,它几乎可以工作。我下面的代码基本上暂时进行了详细刷新对主 ADO 查询应用过滤器以将其过滤到当前主行,并且在该过滤器生效时,通过应用类似的过滤器来刷新主 CDS,然后调用其 Refresh 方法。这是由主 CDS AfterScroll 事件触发的。
只有一个很小问题:在我的表单以及 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 刷新代码如果在主 CDS 的 AfterScroll 事件中调用,则行为会有所不同,其中详细信息 CDS 始终会正确更新,并且在 ButtonClick 处理程序中,其中详细 CDS 仅在每秒单击一次时更新。我想那是某事与主 CDS 的光标此时已经移动的事实有关与我单击按钮的情况不同,调用 AfterScroll 处理程序。
但是,我找到了一个简单的解决方法和修复方法。
解决方法就是不要在之前的 4 个数据集上调用 DisableControls进行刷新。然后详细 CDS 始终会正确刷新。任何其他禁用部分或全部数据集的排列会导致我的 q 的差异。不过,我不喜欢这种解决方法,因为 cdsMaster DBGrid 必须一直滚动数据,只需刷新一个主行及其详细信息即可。
解决办法是做一些我一开始就应该做的事情,即强制详细 ADO 查询的刷新(使用我的数据,只需调用其刷新,这是我的第一次尝试在修复时,会引发熟悉的 Ado 错误“关键列信息不足用于更新...”尽管详细信息表在服务器上有一个 PK)。
因此,解决方法如下:
procedure TForm1.qMasterRowRefresh(MasterPK : Integer);
begin
try
qMaster.Filter := MasterPKName + ' = ' + IntToStr(MasterPK);
qMaster.Filtered := True;
qMaster.Refresh;
// Do NOT omit the next 3 lines, needed to ensure that the detail query
// and hence the detail CDS, is refreshed
qDetail.Parameters.ParamByName(MasterPKName).Value := MasterPK;
qDetail.Close;
qDetail.Open;
cdsMasterRowRefresh(MasterPK);
finally
qMaster.Filtered := False;
qMaster.Locate(MasterPKName, MasterPK, []);
end;
end;
当我通过调查一个早期未回答的问题来进入这个问题时,我会将代码的更新版本移植到该版本的答案。
关于delphi - 刷新嵌套在 DataSetField 中的 ClientDataSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24685699/
我几乎已经完成了一些代码来解决去年这个未回答的问题中的问题: Refresh Nested DataSet with poFetchDetailsOnDemand 公认的观点是,如果不关闭并重新打开主
我是一名优秀的程序员,十分优秀!