delphidbgridtdataset

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


I have descended a class from TDBGrid, and I want it to be able to remember any modifications that a particular user makes to the column order and column width. And, I want to be able to do this entirely within the grid itself. I do not want to have to attach code to the TDataSet, since this grid is used extensively in my application and I want to implement this feature in all of my grids without duplicating code.

I’ve got the persistence part down. I am able to detect that a user has made changes to the grid columns during their session, and persist that information when either the associated TDataSet is closing, or the grid itself is being destroyed. If you are interested, capture the column parameters from the overwritten ColumnMoved method, as well as from the overwritten ColsWidthChanged method. (Note that this must only be done from the ColsWidthChanged when the FGridState field is equal to gsColSizing.)

I can also retrieve the persisted information when the grid is being initialized but before it is displayed. My problem is that while I am successful at restoring the persisted column order and their widths, those setting are lost before the grid is displayed. Specifically, immediately after applying the persisted settings I can confirm that I have restored the saved column order and widths. But by the time the grid is displayed, it shows the default column order and widths. This suggests that I am applying the persisted settings too early in the loading process.

(By the way, you change the order of the TColumns in a TDBGrid by changing the individual TColumn.Index property. There is also a MoveColumn method. These techniques work once the default TColumns have already been created and configured.)

I am trying to restore previously persisted column settings from within the overwritten LinkActive method, when the value of the parameter to this method is equal to True.

I have inspected the various grid classes in the DBGrid hierarchy, and I simple don’t see a method to override that is later in the load cycle. Does anyone out there have a suggestion for an approach that will succeed in restoring previously save column order definitions immediately prior to the grid displaying the contents of the underlying TDataSet. Again, I want to do this entirely from the grid without having to assign an event handler to the TDataSet. On the other hand, if I need to override a method in something internal to the TDBGrid, such as its TGridDataLink, that would be fine.

Edit - - - - - - - - - - - - - - - - -

It appears that overriding LinkActive and testing for the parameter True (and with a little more finesse, such as making sure that you haven't already loaded the persisted data), is the correct way to do this. My problem was that my loading of the persisted data had some issues. Specifically, as I changed the positions of the default fields, other fields also changed positions, and these changes needed to be accounted for.

Edit 2 - - - - - - - - - - - - - - - - - -

Ok, this one is solved. While I had the persistence part working, I made an error in the restoration. So, here what was needed. In order to rearrange the columns, based on the new order that was persisted, you also have to know the default, or current, order of those fields. The trick is that as you start to change the order of columns in the Columns property, you also have to change your list of the current positions of the fields. I had failed to do this.

My code now not only changes the order of the fields in the TColumns property of the grid, but it also updates the list that I created to keep track of the current order.


Solution

  • It turns out that overriding LinkActive in the TDBBGrid class is a fine place to restore previously persisted column position data (see the edits to my question for more info). So, the problem was not in the choice of methods to override.

    You may recall from my question that you change the order of the TColumns in a TDBGrid by changing the TColumn.Index property of the individual columns. There is also a MoveColumn method. However, in order for these to work, you have to know the current position of the fields in the Columns property. While I captured this information before restoring the saved positions, what I overlooked was that the current position of many of the fields change each time I change the order of a given field. Once I realized that, I not only changed the order of the fields in Columns, but I also updated my list containing the current positions of the fields.