[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]

    OVERVIEW

      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 panel with DataSource and
    DataField properties similar to the TDBText component.  See the
    Component Writer's Guide "Making a Control Data-Aware" for further
    examples.

    WHO SHOULD USE THIS DOCUMENT

      To get the best use of this document, you should be familiar
    with data aware control functionality and fundamental component
    creation tasks, such as

    -- deriving components from existing components

    -- overriding constructor and destructors

    -- creating new properties

    -- getting and setting property values

    -- assigning event handlers

    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.
       The TCustomPanel 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.

       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 components 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 DataSource.  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: Our new component will have DataField and DataSource
       properties and FDataLink will also have its own DataField and
       Datasource properties.

      { example }
      published
        property DataField: string
          read   GetDataField
          write  SetDataField;
        property DataSource: TDataSource
          read   GetDataSource
          write  SetDataSource;

    -- 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;
        function GetDataField: String;
        function GetDataSource: TDataSource;
        procedure SetDataField(Const Value: string);
        procedure SetDataSource(Value: TDataSource);
        .
        .
      implementation
        .
        .
      function TDBPanel.GetDataField: String;
      begin
        Result := FDataLink.FieldName;
      end;

      function TDBPanel.GetDataSource: TDataSource;
      begin
        Result := FDataLink.DataSource;
      end;

      procedure TDBPanel.SetDataField(Const Value: string);
      begin
        FDataLink.FieldName := Value;
      end;

      procedure TDBPanel.SetDataSource(Value: TDataSource);
      begin
        FDataLink.DataSource := Value;
      end;

    -- Add a private DataChange method to be assigned to the
       datalink'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
        .
        .
        procedure DataChange(Sender: TObject);

      implementation
        .
        .
      procedure TDBPanel.DataChange(Sender: TObject);
      begin
        if FDataLink.Field = nil then
          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
        constructor Create(AOwner: TComponent); override;
        .
        .
      implementation
        .
        .
      constructor TMyDBPanel.Create(AOwner: TComponent);
      begin
        inherited Create(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
        .
        .
        destructor Destroy; override;
        .
        .
      implementation
        .
        .
      destructor TDBPanel.Destroy;
      begin
        FDataLink.OnDataChange := nil;
        FDataLink.Free;
        inherited Destroy;
      end;

    -- Save the unit and install the component (see the Users
       Guide, and the Component Writers Guide 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
       TTable DatabaseName and Tablename to 'DBDemos' and 'BioLife',
       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.

    FULL SOURCE LISTING

    unit Mydbp;

    interface

    uses
      SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
      Forms, Dialogs, ExtCtrls, DB, DBTables;

    type
      TDBPanel = class(TCustomPanel)
      private
        FDataLink: TFieldDataLink;
        function GetDataField: String;
        function GetDataSource: TDataSource;
        procedure SetDataField(Const Value: string);
        procedure SetDataSource(Value: TDataSource);
        procedure DataChange(Sender: TObject);
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
        property DataField: string
          read   GetDataField
          write  SetDataField;
        property DataSource: TdataSource
          read   GetDataSource
          write  SetDataSource;
      end;

      procedure Register;

    implementation

      procedure Register;
      begin
        RegisterComponents('Samples', [TDBPanel]);
      end;

      function TDBPanel.GetDataField: String;
      begin
        Result := FDataLink.FieldName;
      end;

      function TDBPanel.GetDataSource: TDataSource;
      begin
        Result := FDataLink.DataSource;
      end;

      procedure TDBPanel.SetDataField(Const Value: string);
      begin
        FDataLink.FieldName := Value;
      end;

      procedure TDBPanel.SetDataSource(Value: TDataSource);
      begin
        FDataLink.DataSource := Value;
      end;

      procedure TDBPanel.DataChange(Sender: TObject);
      begin
        if FDataLink.Field = nil then
          Caption := ''
        else
          Caption := FDataLink.Field.AsString;
      end;

      constructor TDBPanel.Create(AOwner: TComponent);
      begin
        inherited Create(AOwner);
        FDataLink := TFieldDataLink.Create;
        FDataLink.OnDataChange := DataChange;
      end;

      destructor TDBPanel.Destroy;
      begin
        FDataLink.Free;
        FDataLink.OnDataChange := nil;
        inherited Destroy;
      end;

    end.

[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]