TDBCtrlGrid Problems

The TDBCtrlGrid is used to display the values returned with a DataSet (TDataSource) by placing various DB components on a panel. When the application is run, the panel is replicated with one copy per record.

However, there are numerous problems using this component.

Buttons - Panel New Buttons | LookUp Components


Buttons

There are several uses for buttons on a control grid However, the standard Delphi 5 buttons can not be added to TDBCtrlGrid's (you get an error if you try) because the components are not defined as Replicatable.

These controls are Replicatable

It is fairly simple to create a new component and make it Replicatable.


Panel

One way to fake a button is to simulate one with a TPanel (based on TCustomPanel) - simply change BevelOuter when the mouse is pressed an released. This is not too bad, but it does require attaching these routines to every simulated button on every form that needs a button in a DBCtrlGrid. Also, additional code is required to add other button characteristics - such as having the button pop up when the mouse is held down and moved off the button.


New Buttons

It is fairly simple to create a new button component and add csReplicatable to its ControlStyle. I have created 2 of these This is the relevent code. Of course, these need to be added to a package and registered before they can be used.

There is a reason that Delphi didn't do this for us - I am sure that some normal button features will fail in this situation. So be careful. For instance, I do not suggest setting any properties that only one button on a form should have - such as Cancel or Default. I also would not use any Actions.

OnClick does work (that is the point of this) ... references to fields in the same DBCtrlGrid panel return the correct value.


LookUp Components

Delphi provides 2 LookUp components On a form, these components display data from one table based on a key in another (a very useful function).

The problem is that when they are placed on a TDBCtrlGrid, there is no simple way to "lookup" data from another table (because you can NOT set ListSource in a DBCrtlGrid).

There is practically no help on this problem, either in Delphi or online.


Use DBComboBox

Manually query the database and build the DBComboBox list.

This code gets the names of all the non-system generators.


Add a Lookup Field

It is possible to manually add fields to some IB components. The idea to to add one of these and to define it as a lookup field.

This is from the TDBLookupControl.ListSource help

If the DataField field is a lookup field, ... data controls automatically use the lookup field's LookupDataSet property to create a data source.
No examples ... of course :(

The following works

The hardest part of this to figure out was that you MUST select Add all fields to make it work. Apparently, this normally occurs automatically if NO fields are manually included ... however, once you create the lookup field, you must manually add all the others. (Actually, a small subset of the available fields will also work ... as long as the linked field (Key Field) is included.) In hindsite, the various error messages were crystal clear. However, I simply did not understand what they were saying until I had it all figured out. Numerous web searches produced no examples ... just a few hints that I might eventually get it to work.

It is possible to display a value based on combining several key fields - the Delphi help explains how to do it.

For more information, read these topics in the Delphi help


Copy the Lookup List

I have not tested this.

This technique requires placing one LookUp component on the form (outside the DBCtrlGrid) and connecting that to the lookup table. Then the lookup list is copied to the TDBCombo box in the DBCtrlGrid.


Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Databases / Delphi / DBCtrlGrid_Problems.html