However, there are numerous problems using this component.
Buttons
These controls are Replicatable
type // Generic button for use on a DBCtrlGrid TDB_xxButton = class(TButton) constructor TDB_xxButton.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle + [csReplicatable]; end;
Panel
// Together, the following methods allow any panel to simulate a button // This is necessary because regular buttons can not be added // to DBCtrlGrid's procedure TMain_Form.Panel_MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // This simulates a button (Sender as TPanel).BevelOuter := bvLowered; end; procedure TMain_Form.Panel_MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // This simulates a button (Sender as TPanel).BevelOuter := bvRaised; end; // End of code that allows panels to simulate buttonsThis 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
type // Generic button for use on a DBCtrlGrid TDB_mcButton = class(TButton) public constructor Create(AOwner: TComponent); override; end; // Generic button for use on a DBCtrlGrid - smaller size, shows 3 dots TDB_mc3DotButton = class(TButton) public constructor Create(AOwner: TComponent); override; end; implementation constructor TDB_mcButton.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle + [csReplicatable]; end; constructor TDB_mc3DotButton.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle + [csReplicatable]; Caption := '...'; Height := 19; Width := 19; end;Of course, these need to be added to a package and registered before they can be used.
procedure Register; begin RegisterComponents('mc', [TDB_mcButton, TDB_mc3DotButton]); end;
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.
procedure TForm1.DB_mc3DotButton1Click(Sender: TObject); begin ShowMessage(DBEdit1.Text); end;
LookUp Components
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
This code gets the names of all the non-system generators.
SamplesDataModule : TBasicDataModule ; procedure TForm1.FormCreate(Sender: TObject); var s : string; begin s := 'select * from RDB$GENERATORS ' + ' where RDB$GENERATOR_NAME not like ''%$%''' ; SamplesDataModule.Load_TStrings_via_Query (s, 'RDB$GENERATOR_NAME', Generators_UIComboBox.Items); Generators_UIComboBox.ItemIndex := 0; Generators_UIComboBoxChange(sender); end; procedure TBasicDataModule.Load_TStrings_via_Query (Query, DataField :string; StrList: TStrings); var flag : boolean; s : string ; begin StrList.Clear; ExecuteSelectSQL(Query); // this uses IBQuery_Basic while not IBQuery_Basic.eof do begin s := IBQuery_Basic.FieldByName(DataField).AsString; StrList.Add(s); IBQuery_Basic.Next; end; end; // Load_TStrings_via_Query
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
Name | Any value you want - I suggest something ending with "LLU" or "LocalLU" so these are easier to identify, this is displayed in the lists of table fields | |
Component | This is automatically filled in for you - it becomes the name of the component | |
Type | I always use string | |
Size | This should be the size of the data that will be displayed, defaults to 20 if left blank | |
Field type | Select Lookup - This enables the next 2 fields | |
Key Fields | Select one from the list | |
Dataset | Select one from the list - This enables the last 2 fields | |
Lookup Keys | This is the key (lookup) field in the lookup table, select it from the list | |
Result Field | This field contains the value that will be displayed, select it from the list |
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
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