【发布时间】:2012-02-23 15:34:21
【问题描述】:
我的 C++ CAD 应用程序维护用户建模操作的日志,以便可以取消应用和重新应用它们。任何特定项目可能只包含几个操作,也可能包含数十万个操作。我已经有了自己的数据结构,可以以一种内存效率高的方式管理这些数据,而且效果很好。但现在我添加了一个功能,允许用户在网格中检查他的操作日志。 (我使用的是 Embarcadero RAD Studio 2010;所有的 GUI 都使用 VCL。)
目前,我正在使用 TDBGrid 组件向用户显示行中的操作数据。以下是我连接组件的方式:
TDBGrid.DataSource = 一个 TDataSource
TDataSource.DataSet = 一个 TClientDataSet
TClientDataSet.ProviderName = 一个 TDataSetProvider
TDataSetProvider.DataSet = 一个 ProjectDataSet
ProjectDataSet 是我从 TDataSet 派生的一个类。
因为我是从我自己的数据结构中而不是从数据库中提取操作数据,所以我在我的 ProjectDataSet 类中重写了 GetFieldData 和 GetRecord 函数(以及其他几个函数),以便它直接从我自己的数据结构中返回数据(不做任何数据库查询)。这行得通。
为了在显示大量操作时最大限度地减少内存使用,我在 TClientDataSet 中设置了“FetchOnDemand”属性,并将“PacketRecords”设置为 100。因此,最初只有前 100 个操作出现在网格中。一旦用户滚动到网格底部,接下来的 100 个操作将由 TClientDataSet 自动获取并显示在网格中。
所有这些都非常有效。我的问题是,当用户在网格中滚动时,TClientDataSet 会继续获取越来越多的记录,而不会释放任何记录。所以,如果用户在一个非常大的项目中向下滚动足够远,我最终会耗尽内存。
所以,我的问题是:让这个 GUI 工作的最佳方法是什么?本质上,我希望网格表现得像电子表格。我希望用户能够在操作列表中上下滚动(或跳转到特定行),不管有多少操作,我不希望 GUI 组件在内存中保留很多东西用户并不迫切需要。
我假设 TDBGrid(或其他一些 VCL 组件)被设计为能够通过一次仅获取几条记录来显示任意大的数据集,那么它是如何完成的呢?
如果我需要重新考虑 GUI,那很好。但是如果我可以使用同一个 GUI 来显示 10 个操作项目或 100,000 个操作项目,那就太好了。
谢谢。
【问题讨论】:
-
如果在添加下一个数据包之前手动清除 cd 会怎样?
-
是的,这可能行得通。我会试一试。不过,我觉得它正在破解它。我真正在寻找的是 正确的 方法。我认为 VCL 旨在能够在网格中显示任意大的数据集,我想知道这是如何工作的。感谢您的帮助。
-
请报告您的结果。事实上,恐怕没有“正确”的方法可以做到这一点,CDS 和整个 TDataSet 设计不足
标签: c++builder vcl tclientdataset tdbgrid tdataset