在运行时从 Delphi TDBGrid 后代显示 DBGrid 之前,如何以编程方式更改 TColumn 属性?

How do I change TColumn properties programmatically prior to showing a DBGrid at runtime from a Delphi TDBGrid descendant?

我从 TDBGrid 继承了一个 class,我希望它能够记住特定用户对列顺序和列宽所做的任何修改。而且,我希望能够完全在网格内完成此操作。我不想将代码附加到 TDataSet,因为这个网格在我的应用程序中被广泛使用,我想在我的所有网格中实现这个特性而不需要复制代码。

我把持久性部分搞定了。我能够检测到用户在会话期间对网格列进行了更改,并在关联的 TDataSet 关闭或网格本身被销毁时保留该信息。如果您有兴趣,可以从覆盖的 ColumnMoved 方法以及覆盖的 ColsWidthChanged 方法中捕获列参数。 (请注意,这只能在 FGridState 字段等于 gsColSizing 时从 ColsWidthChanged 完成。)

我还可以在初始化网格时但在显示之前检索持久化信息。我的问题是,虽然我成功恢复了持久的列顺序及其宽度,但这些设置在显示网格之前就丢失了。具体来说,在应用持久设置后,我可以立即确认我已经恢复了保存的列顺序和宽度。但是在显示网格时,它会显示默认的列顺序和宽度。这表明我在加载过程中过早地应用了持久设置。

(顺便说一句,您可以通过更改单个 TColumn.Index 属性 来更改 TDBGrid 中 TColumns 的顺序。还有一个 MoveColumn 方法。一旦默认的 TColumns 具有已经创建和配置。)

当此方法的参数值等于 True 时,我正在尝试从覆盖的 LinkActive 方法中恢复以前保留的列设置。

我已经检查了 DBGrid 层次结构中的各种网格 classes,我只是没有看到在加载周期的后期覆盖的方法。有没有人建议在网格显示基础 TDataSet 的内容之前立即成功恢复先前保存的列顺序定义的方法。同样,我想完全从网格执行此操作,而不必将事件处理程序分配给 TDataSet。另一方面,如果我需要重写 TDBGrid 内部的某个方法,例如它的 TGridDataLink,那就没问题了。

编辑 - - - - - - - - - - - - - - -

似乎重写 LinkActive 并测试参数 True(并更巧妙一些,例如确保您尚未加载持久化数据)是执行此操作的正确方法。我的问题是我对持久数据的加载有一些问题。具体来说,当我更改默认字段的位置时,其他字段的位置也发生了变化,需要考虑这些变化。

编辑 2 - - - - - - - - - - - - - - - -

好的,这个就解决了。当我让持久性部分工作时,我在恢复时犯了一个错误。所以,这里需要什么。为了根据保留的新顺序重新排列列,您还必须知道这些字段的默认或当前顺序。诀窍在于,当您开始更改 Columns 属性 中的列顺序时,您还必须更改字段当前位置的列表。我没有做到这一点。

我的代码现在不仅更改了网格的 TColumns 属性 中字段的顺序,而且还更新了我创建的用于跟踪当前顺序的列表。

事实证明,覆盖 TDBBGrid class 中的 LinkActive 是恢复以前保留的列位置数据的好地方(有关更多信息,请参阅对我的问题的编辑)。所以,问题不在于选择要覆盖的方法。

您可能还记得我的问题,您通过更改各个列的 TColumn.Index 属性 来更改 TDBGrid 中 TColumns 的顺序。还有一个 MoveColumn 方法。但是,为了使它们起作用,您必须知道字段在列 属性 中的当前位置。虽然我在恢复保存的位置之前捕获了这些信息,但我忽略的是,每次我更改给定字段的顺序时,许多字段的当前位置都会发生变化。意识到这一点后,我不仅更改了列中字段的顺序,还更新了包含字段当前位置的列表。