【问题标题】:Issue with posting correct data with disablecontrols使用 disablecontrols 发布正确数据的问题
【发布时间】:2016-08-15 21:53:35
【问题描述】:

我在迭代 DataSet 时(即更新字段时)使用 Disable/EnableControls() 时遇到了一些问题。

这两个更新后的字段似乎发生了什么,它们都采用相同的数据。看起来正在为所有行输入帖子的最后一个值。因此,假设我们有 3 条记录,它们更新了 1、2 和 3 的值(在我的情况下,所有字段都发布了 3),而我期望最后一个字段是 1、2 和 3。

例如,我的数据集中有 10 条记录。我运行这个函数,在查看网格和持久化数据时,每行的Cost 列值都是相同的,即使我已经逐步检查并关注了getNewDataValue 函数,它们是不同的值。

NumberSelected = 0;
dataSourceItems.DataSet.DisableControls; //it this be my problem, accessing the dataset via the datasource? – I tried this and it didn’t make a difference.
while (NumberSelected < cxGridDBTableView1.Controller.SelectedRowCount) do
begin
  Id = cxGridDBTableView1.Controller.SelectedRows[NoSelected]).Values[0];
  if dataSourceItems.DataSet.locate('PK', Id, []) then 
  begin
    dataSourceItems.DataSet.edit;
    dataSourceItems.DataSet.fieldbyname('Cost').asfloat := getNewDataValue;
    dataSourceItems.DataSet.Post;
    inc(NumberSelected)
  end;

  dataSourceItems.DataSet.EnableControls;
end;

我正在使用 Delphi 2010、DevExpress Quantum Grid 和 FIBPlus 数据集访问 Firebird 数据库。

查看文档,我可以看到当调用 DisableControls() 时,TDataSet.DataEvent 不会将事件传递给 DataSources,并且所有主从关系都被破坏,直到调用 EnableControls()。 会不会是我通过 DataSource 访问 DataModule 上的 DataSet?这个我试过了,没什么区别。

不使用Disable/EnableControls(),速度无法使用。 因此,任何快速迭代大型 DataSet 的建议或替代方法都会有所帮助。

【问题讨论】:

  • 你不应该依赖(就像你现在一样)在行光标移动之前发布到数据集的更改。在您的 fieldbyname() 分配之后立即显式调用 dataSourceItems.DataSet.Post。试试看 - 它可能会自行解决您的问题,但无论如何您都应该这样做。
  • 为清楚起见编辑了我的问题,因为我实际上并没有明确地发出帖子。你的权利,我现在就改变和测试。
  • 顺便说一句,最不容易出错的方法是在选定行 ID 的情况下构建一个列表,然后在处理选定行时暂时将数据集完全与 cxGrid 断开连接。这起作用。
  • Disable/EnableControls 不会影响数据是否发布,或者数据集是否接收任何分配的事件。它只影响附加到其字段的控件是否更新(IOW,它只影响 UI)。我已经使用数据感知控件数十年(字面意思)并且从未遇到过 DisableControls 干扰正确更新和保存数据的问题。我怀疑您遇到的是 cxGrid 中的错误 - 我经常在使用网格的 Advantage Data Utility (ARC32) 中看到它。如果执行查询,将焦点设置在网格上,然后快速滚动,
  • (续)网格似乎包含许多重复的行。 (有时看起来所有的行都是相同的。)当您停止滚动时,显示会赶上并显示正确的行。由于这只发生在 ARC32 中,而且我无法使用标准 DBGrid 对相同的数据和查询进行处理,因此我确定问题出在 cxGrid 上。

标签: delphi delphi-2010 fibplus


【解决方案1】:

你是从循环内部调用EnableControls(),而它应该在循环外部(最好在try..finally块中)。

但更重要的是,您不会增加NoSelected,因此每次进行编辑时您总是访问相同的选定 ID。您有两个变量在努力完成一个变量本身应该完成的工作。

试试这个:

NumberSelected = 0;
dataSourceItems.DataSet.DisableControls;
try
  while (NumberSelected < cxGridDBTableView1.Controller.SelectedRowCount) do
  begin
    Id = cxGridDBTableView1.Controller.SelectedRows[NumberSelected]).Values[0];
    if dataSourceItems.DataSet.Locate('PK', Id, []) then 
    begin
      dataSourceItems.DataSet.Edit;
      dataSourceItems.DataSet.FieldByName('Cost').AsFloat := getNewDataValue;
      dataSourceItems.DataSet.Post;
    end;
    Inc(NumberSelected);
  end;
finally
  dataSourceItems.DataSet.EnableControls;
end;

或者:

dataSourceItems.DataSet.DisableControls;
try
  for NumberSelected = 0 to cxGridDBTableView1.Controller.SelectedRowCount-1 do
  begin
    Id = cxGridDBTableView1.Controller.SelectedRows[NumberSelected]).Values[0];
    if dataSourceItems.DataSet.Locate('PK', Id, []) then 
    begin
      dataSourceItems.DataSet.Edit;
      dataSourceItems.DataSet.FieldByName('Cost').AsFloat := getNewDataValue;
      dataSourceItems.DataSet.Post;
    end;
  end;
finally
  dataSourceItems.DataSet.EnableControls;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多