Navigation

How to create data-aware components

This document describes minimal steps necessary to create a data-aware
browsing component that displays data for a single field. The example
component is a TPanel descendant with DataSource and
DataField properties similar to the TDBText component.
&quout;Making a Control Data-Aware" in the Component Writer's Guide in
the Delphi help file for further examples.

Basic steps to create a data-browsing component

Create or derive a component that allows the display, but not the entry of
data. For instance, you could use a TMemo with ReadOnly
set to true. In the example outlined in this document, we'll use a
TCustomPanel. This will allow display, but not data entry.

Add a data-link object to your component. This object manages communication
between the component and the database table.

Add DataField and DataSource properties to the
component.

Add methods to get and set the DataField and
DataSource.

Add a DataChange method the component to handle the data-link
object's OnDataChange event.

Override the component constructor to create the datalink and hook up the
DataChange method.

Override the component destructor to cleanup the datalink.

Creating the TDBPanel

Create or derive a component that allows the display, but not the entry of
data. We'll be using a TCustomPanel as a starting point for this
example.

In Delphi, choose the appropriate menu option to create a new component (this
will vary between editions of Delphi), and specify TDBPanel as the
class name, and TCustomPanel as the ancestor type. You may specify
any palette page.

Add DB and DBTables to your uses
clause.

Add a data-link object to the component's private section. This example will
display data for a single field, so we will use a TFieldDataLink to
provide the connection between our new component and a data-source. Name the
new data-link object FDataLink. Example:

private

FDataLink:TFieldDataLink;

Add DataField and DataSource properties to the
component. We will add supporting code for the get and set methods in
following steps. Note that our new component will have DataField
and DataSource properties and FDataLink will also have
its own DataField and Datasource properties. Example:

published

propertyDataField:stringreadGetDataFieldwriteSetDataField;

propertyDataSource:TDataSourcereadGetDataSourcewriteSetDataSource;

Add private methods to get and set the DataField and
DataSource property values to and from the DataField and
DataSource for FDataLink. Example:

...

private

FDataLink:TFieldDataLink;

functionGetDataField:String;

functionGetDataSource:TDataSource;

procedureSetDataField(ConstValue:string);

procedureSetDataSource(Value:TDataSource);

...

implementation

functionTDBPanel.GetDataField:String;

begin

Result:=FDataLink.FieldName;

end;

functionTDBPanel.GetDataSource:TDataSource;

begin

Result:=FDataLink.DataSource;

end;

procedureTDBPanel.SetDataField(ConstValue:string);

begin

FDataLink.FieldName:=Value;

end;

procedureTDBPanel.SetDataSource(Value:TDataSource);

begin

FDataLink.DataSource:=Value;

end;

Add a private DataChange method to be assigned to the data-link's
OnDataChange event. In the DataChange method add code to
display actual database field data provided by the data-link object. In this
example, we assign FDataLink's field value to the panel's caption.
Example:

...

private

procedureDataChange(Sender:TObject);

...

implementation

procedureTDBPanel.DataChange(Sender:TObject);

begin

ifFDataLink.Field=nilthen

Caption:='';

else

Caption:=FDataLink.Field.AsString;

end;

Override the component constructor Create method. In the
implementation of Create, create the FDataLink object,
and assign the private DataChange method to FDataLink's
OnDataChange event. Example:

...

public

constructorCreate(AOwner:TComponent);override;

...

implementation

constructorTMyDBPanel.Create(AOwner:TComponent);

begin

inheritedCreate(AOwner);

FDataLink:=TFieldDataLink.Create;

FDataLink.OnDataChange:=DataChange;

end;

Override the component destructor Destroy method. In the
implementation of Destroy, set OnDataChange to nil
(avoids a GPF), and free FDatalink. Example:

...

public

destructorDestroy;override;

...

implementation

destructorTDBPanel.Destroy;

begin

FDataLink.OnDataChange:=nil;

FDataLink.Free;

inheritedDestroy;

end;

Save the unit and install the component (see the Users Guide, and the
Component Writers Guide in Delphi Help for more on saving units and installing
components).

To test the functionality of the component, add a TTable,
TDatasource, TDBNavigator and TDBPanel to a
form. Set the TTableDatabaseName and
TableName to 'DBDemos' and 'BioLife' respectively, and the
Active property to True. Set the
TDatasource.Dataset property to Table1. Set the
TDBNavigator and TDBPanel.DataSource property to
Datasource1. The TDBPanel.DataField name should be set
as 'Common_Name'. Run the application and use the navigator to move between
records to demonstrate the TDBPanel's ability to detect the change
in data and display the appropriate field value.