⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teedbtre.pas

📁 第三方控件:PaintGrid.pas 网格型仪表控件源文件 Mymeter.pas 圆型仪表控件源文件 Project1是这两个控件的使用范例。 该
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{**********************************************}
{   TDBTree Database Tree Component            }
{   Copyright (c) 1998-2002 by David Berneda   }
{**********************************************}
{$I TeeDefs.inc}
unit TeeDBTre;

{ Linking a Tree component to a Database Table or Query
  (or any other DataSet), is easy just by setting some
  properties.

  Use the "Database Wizard Dialog" to connect DBTree components to
  Tables or Queries.

  For more advanced layouts, use the Layout collection property.

  It's also easy to do it by code. Follow the instructions below.

  Related Property:
  =================
    MultiLineText : Boolean   ( default True )

    When True, Tree nodes are filled with several lines of text.
    When False, text is joined into a single line.


 Situations:
 ===========

  Situation 1:
  ============

    We have a table or query which includes a "Code and Parent"
    fields:

       Code   Parent Text
       ------ ------ ------------
          1     0    Continents
          2     1      America
          3     1      Africa
          4     1      Australia
          5     2        USA
          6     5          California
          7     4        Sydney
          ..    ...    ...


    We want to create a tree like this:

       Continents -> America -> USA -> California
                  -> Africa
                  -> Australia -> Sydney

    We need to set the following properties:

      With DBTree1 do
      begin
        DataSet     := Table1 ;
        CodeField   := 'Code' ;
        ParentField := 'Parent' ;
        TextFields  := 'Text';
        Refresh;
      end;

    If we need several fields for "text", we can use this syntax:

      DBTree1.TextFields   := 'Text;OtherText;OtherField';


  Situation 2:
  ============

     We have a Table or Query or any other DataSet but it does not
     include a "Parent" or "Code" field.

     We have this data:


        Country      City
        ----------   ---------------
        AUSTRALIA    Sydney
        USA          New York
        UK           London
        AUSTRALIA    Camberra
        UK           Manchester
        UK           Liverpool
        USA          Michigan
        USA          Chicago

     And the tree we need is:

        AUSTRALIA -> Sydney
                  -> Camberra

        UK        -> Liverpool
                  -> London
                  -> Manchester

        USA       -> Chicago
                  -> Michigan
                  -> New York


     The code we need is:

       With DBTree1 do
       begin
         DataSet     := Table1 ;
         CodeField   := '';
         ParentField := 'Country' ;
         TextFields  := 'City' ;
         Refresh;
       end;


     Additionally you can expand the first root node:

         DBTree1.Roots[0].Expanded:=True;

  Situation 3:
  ============

     We have a master-detail relation between to tables or queries
     (or any other types of datasets):

       Master dataset:

             Person   Department
             -------  --------------
             John     Accounting
             Chris    Management
             Anne     Sales
             Peter    Accounting
             James    Sales
             Linda    Sales

       Detail dataset:

             Person  Month  Salary
             ------- ------ ----------
             John    April  $1000
             John    May    $1100
             John    June   $800
             John    July   $1200
             ...
             Chris   March  $900
             Chris   April  $700
             Chris   May    $500
             ...
             Anne...


       We want the following tree:

           Department -> Accounting -> John -> April $1000
                                            -> May $1100
                                            -> June $800
                                            -> July $1200
                                    -> Peter

                      -> Management -> Chris -> March $900
                                             -> April $700
                                             -> May $500

                      -> Sales -> Anne
                               -> James
                               -> Linda


     The code to use is:

       With DBTree1 do
       begin
         DataSet     := Table1 ;  ( the master table )
         CodeField   := '';
         ParentField := 'Department' ;
         TextFields  := 'Person' ;
         Detail      := Table2 ;  ( the detail table )
         DetailFields:= 'Month;Salary' ;
         Refresh;
       end;

     More Advanced Situations:
     =========================

     When having more than one master-detail relationship (more than 2 datasets)
     or for special db-trees, add more DBLayout items, either at design-time
     or runtime.

    }
interface

uses
  {$IFNDEF LINUX}
  Windows, Messages,
  {$ENDIF}
  SysUtils, Classes,
  {$IFDEF CLX}
  QGraphics, QControls, QForms, QDialogs, QExtCtrls,
  {$ELSE}
  Graphics, Controls, Forms, Dialogs, ExtCtrls,
  {$ENDIF}
  {$IFDEF CLR}
  Contnrs, Variants,
  {$ENDIF}
  TeeProcs, TeeTree, DB;

Const MaxFields = 20;

type
  EDBTreeException=class(Exception);
  TCustomDBTree=class;

  TMaxDBTreeFields=Array[0..MaxFields-1] of TField;
  TDBTreeFields=Packed Record
    Count : Integer;
    Field : TMaxDBTreeFields;
  end;

  TDBLayoutDisplay=(ldSingle,ldMultiLine,ldGrid);

  TDBLayout=class(TCollectionItem)
  private
    FCodeField    : String;      // used only in situation "1" ( Parent->Code )
    FDataSet      : TDataSet;         // the dataset
    FDisplayMode  : TDBLayoutDisplay; // the display mode (single line, multi, grid)
    FHeaderFormat : TTreeNodeShape;   // optional header text and format
    FParentField  : String;           // List of field names to do group by
    FFormat       : TTreeNodeShape;   // optional shape determining the node format
    FFields       : String;           // List of field names to display
  private
    ICodeField   : TField;
    IDetails     : {$IFDEF CLR}TObjectList{$ELSE}TList{$ENDIF};
    IFields      : TDBTreeFields;
    IParents     : TDBTreeFields;

    Function AddNode(AParent:TTreeNodeShape):TTreeNodeShape;
    Procedure AddNodeText(ANode:TTreeNodeShape; Var AFields:TDBTreeFields);
    Function AddText(AChild:TTreeNodeShape):TTreeNodeShape;
    Procedure RunNextLayouts(ADetailRoot:TTreeNodeShape);
    procedure SetDataSet(const Value: TDataSet);
    procedure SetFields(const Value: String);
    procedure SetCodeField(const Value: String);
    procedure SetParentField(const Value: String);
    procedure SetFormat(const Value: TTreeNodeShape);
    function GetFormat: TTreeNodeShape;
    function GetHeaderFormat: TTreeNodeShape;
    procedure SetHeaderFormat(const Value: TTreeNodeShape);
    procedure ReadFormat(Reader: TStream);
    procedure WriteFormat(Writer: TStream);
    procedure ReadHeaderFormat(Reader: TStream);
    procedure WriteHeaderFormat(Writer: TStream);
  protected
    procedure DefineProperties(Filer:TFiler); override;
    Procedure FinishAddingText(ANode:TTreeNodeShape); virtual;
    procedure Prepare; virtual;
    Procedure Run(ARoot:TTreeNodeShape); virtual;
  public
    Destructor Destroy; override;

    Procedure Assign(Source:TPersistent); override;

    Function Tree:TCustomDBTree;
  published
    property DataSet:TDataSet read FDataSet write SetDataSet;
    property DisplayMode:TDBLayoutDisplay read FDisplayMode
                                          write FDisplayMode default ldSingle;
    property HeaderFormat:TTreeNodeShape read GetHeaderFormat write SetHeaderFormat
                                         stored False;
    property Fields:String read FFields write SetFields;
    property CodeField:String read FCodeField write SetCodeField;
    property ParentField:String read FParentField write SetParentField;
    property Format:TTreeNodeShape read GetFormat write SetFormat
                                   stored False;
  end;

  TDBTreeLayout=class(TOwnedCollection)
  private
    Function Get(Index:Integer):TDBLayout;
    Procedure Put(Index:Integer; Const Value:TDBLayout);
  public
    Function Add:TDBLayout;
    property Node[Index:Integer]:TDBLayout read Get write Put; default;
  end;

  TCustomDBTree = class(TCustomTree)
  private
    { Private declarations }
    FLayout: TDBTreeLayout;
    Procedure CreateDetail;
    Procedure CreateParentLayout;
    procedure SetDataSet(const Value: TDataSet);
    procedure SetDetail(const Value: TDataSet);
    procedure CheckDataSet(var ADataSet: TDataSet; const Value: TDataSet);
    procedure SetLayout(const Value: TDBTreeLayout);
    function GetDataSet: TDataSet;
    function GetMultiLineText: Boolean;
    procedure SetMultiLineText(const Value: Boolean);
    function GetTextFields: String;
    procedure SetTextFields(const Value: String);
    function GetCodeField: String;
    function GetDetail: TDataSet;
    function GetDetailFields: String;
    function GetParentField: String;
    procedure SetCodeField(const Value: String);
    procedure SetDetailFields(const Value: String);
    procedure SetParentField(const Value: String);
    function IsLayoutStored: Boolean;
  protected
    IPreviewRecords : Integer;

    { Protected declarations }
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    { Public declarations }
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;

    Function FindNodeCode(ACode:Integer):TTreeNodeShape;
    Procedure Refresh;

    property Layout:TDBTreeLayout read FLayout write SetLayout
                                  stored IsLayoutStored;

    // compatibility with version 1.
    // The new Layout[] property now replaces all these:
    property CodeField:String read GetCodeField write SetCodeField;
    property DataSet:TDataSet read GetDataSet write SetDataSet;
    property Detail:TDataSet read GetDetail write SetDetail;
    property DetailFields:String read GetDetailFields write SetDetailFields;
    property MultiLineText:Boolean read GetMultiLineText write SetMultiLineText
                            default False;
    property ParentField:String read GetParentField write SetParentField;
    property TextFields:String read GetTextFields write SetTextFields;
  end;

  TDBTree=class(TCustomDBTree)
  {$IFNDEF CLX}
  {$IFDEF D4}
  public
    property DockManager;
  {$ENDIF}
  {$ENDIF}
  published
    { TCustomDBTree }
    property CodeField;
    property DataSet;
    property Detail;
    property DetailFields;
    property MultiLineText;
    property ParentField;
    property TextFields;

    { TCustomTree properties }
    property AllowDelete;
    property AllowPanning;
    property BackImage;
    property BackImageMode;
    property BufferedDisplay;
    property CrossBox;
    property Designing;
    property DragAndDrop;
    property Gradient;
    property Grid;
    property HorzScrollBar;
    property HotTrack;
    property Images;
    property Layout;
    property Monochrome;
    property Page;
    property PrintProportional;
    property ReadOnly;
    property ScrollMouseButton;
    property Selected;
    property SingleSelection;
    property ShowHintShapes;
    property ShowRootCross;
    property SnapToGrid;
    property TextEditor;
    property VertScrollBar;
    property View3DOptions;
    property WheelNavigation;
    property Zoom;

    { TCustomTree events }
    property OnAddingConnection;
    property OnAfterDraw;
    property OnBeforeDraw;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -