1

I am writing a grid control that will display the contents of either a TDataSet or a TObjectList. When you only need to support TDataSet, things are quite simple:

  1. Link to the dataset via a TDataLink descendant.
  2. When painting the contents of the grid, you can use the records buffered in that TDataLink to paint what you need to.
  3. There is no need to have individual objects somewhere to represent rows in the TDataSet, because you always just paint the rows in the buffer.

In my case, I need to accept data from a few other sources as well, which meant that I needed to have an object representing each row (also because the control required quite a bit of row state).

But this causes problems with the model described above. Because I have an object representing each row, I need to be informed when records are added or deleted from the TDataSet. And I just cannot see how to do that.

Clearly, I don't want to be hooking to the dataset events; they may already be in use and the TDataLink is meant to be the mediator between my control and the dataset. And my attempts at using the DataEvent virtual method failed, because it simply doesn't tell you if a record is being added/deleted.

Any ideas?

Cobus Kruger
  • 8,338
  • 3
  • 61
  • 106

2 Answers2

1

If you hook your TDataLink descendant to a TDataSource that is connected to the TDataSet you get a call in the RecordChanged procedure when data changes.

You can use the events OnDataChange and OnUpdateData of a TDataSource connected to the TDataSet.

Mikael Eriksson
  • 136,425
  • 22
  • 210
  • 281
  • RecordChanged doesn't tell me what change has occurred. For that matter, I could just have used DataChanged, where I already have some code. And I don't want to use the DataSource events for the same reason I don't use the TDataSet events: Other code (outside my control) will then need to take care saving my event pointers, or my control will break. Not very nice. – Cobus Kruger Jan 11 '11 at 10:58
  • There is a TField argument to RecordChanged. That is the field that has changed on the current record of the associated TDataSet – Mikael Eriksson Jan 11 '11 at 11:36
  • You can use a TDataSource without interfering with users of your grid. There can be many TDataSource object linked to one TDataSet. You assign the DataSet to TDataSource.DataSet. Not the opposite. So there is no need to save/restore event pointers. – Mikael Eriksson Jan 11 '11 at 11:46
  • I ended up linking to the records by using the record number. That done, RecordChanged worked a charm although I needed to keep some internal state to help me determine the type of change. But I was able to determine this without hooking any event handlers, so I'm very happy. – Cobus Kruger Feb 16 '11 at 12:32
0

It seems, you have to derive your own class from the base dataset class you are going to use. There you will need override InternalAddRecord, InternalPost, InternalDelete methods and handle records addition / deletion.

da-soft
  • 7,670
  • 28
  • 36