Показать сообщение отдельно
  #4  
Старый 22.09.2008, 20:55
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Т.е. данные.
Тогда примерно так:
1. "Кладешь" TreeView.
2. При старте (открытии окна) загружаешь верхний уровень. Т.е. выполняешь запрос из Year и создаешь под него итемы. Для каждого итема в проперть Data кладешь ID соотв. записи и, ГЛАВНОЕ, создаешь подитем (пока пустой).
3. На открытие ветки (событие OnExpand) ставишь загрузку соотв. записей из дочерней таблицы, точно также ставя в Data ID и создавая подитемы (естественно, если уровнеь не последний).
4. Повторяешь с п.2., пока не будет написана загрузка всех уровней.

Тут есть еще один момент - как идентифицировать уровень. Я для этого обычно использую проперть StateIndex - она предназначена для хранения номера дополнительной картинки, так что можно вполне ею воспользоваться.

На самом деле это можно написать достаточно красиво и компактно, но при условии, что у тебя структура таблиц имеет некоторую однообразность.

Допустим, у тебя все таблицы имеют поля ID (уникальный идентификатор), ParentID (ссылка на родителя) и Name (собственно некоторое имя, которое и надо загрузить в TreeView).

Тогда будет что-то типа этого:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, DB, DBTables;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    qQuery: TQuery;
    procedure FormCreate(Sender: TObject);
    procedure TreeView1Expanded(Sender: TObject; Node: TTreeNode);
  private
    procedure CreateItems(AParentNode: TTreeNode; AQuery: TDataSet; ALevel : Integer);
    procedure InitLoad;
    procedure Load(AParentNode : TTreeNode);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  levCount = 3;

  levYear = 1;
  levMonth = 2;
  levRealization = 3;

  tableNames : Array [1..levCount] Of String = ('Year','Month','Realisation');

  sqlQuery = 'SELECT ID, Name FROM Year';
  sqlSubQuery = 'SELECT ID, Name FROM %s WHERE ParentID = %d';

procedure TForm1.CreateItems(AParentNode : TTreeNode; AQuery : TDataSet; ALevel : Integer);
var
  ANode : TTreeNode;
begin
  AParentNode.DeleteChildren;
  ADataSet.First;
  While Not ADataSet..EOF Do
     Begin
        ANode := TreeView1.Items.AddChild(AParentNode, AQuery.FieldByName('Name').AsString);
        ANode.Data := Pointer(AQuery.FieldByName('Name').AsInteger);
        ANode.StateIndex := ALevel;
        If ALevel < levCount Then
          TreeView1.Items.AddChild(ANode,'');
        ADataSet.Next;
     End;
end;

procedure TForm1.InitLoad;
begin
  TreeView1.Items.Clear;
  qQuery.Active := False;
  qQuery.SQL.Clear;
  qQuery.SQL.Add(sqlQuery);
  qQuery.Active := True;
  CreateItems(Nil,qQuery,levYear);
  qQuery.Active := False;
end;

procedure TForm1.Load(AParentNode : TTreeNode);
var
  ALevel, AParentID : Integer;
  ASQL : String;
begin
  ALevel := AParentNode.StateIndex;
  AParentID := Integer(AParentNode.Data)
  ASQL := Format(sqlSubQuery,[tableNames[ALevel + 1],AParentID]);
  qQuery.Active := False;
  qQuery.SQL.Clear;
  qQuery.SQL.Add(ASQL);
  qQuery.Active := True;
  CreateItems(AParentID,qQuery,ALevel+1);
  qQuery.Active := False;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  InitLoad;
end;

procedure TForm1.TreeView1Expanded(Sender: TObject; Node: TTreeNode);
begin
  Load(Node);
end;

end.

Естественно, здесь нет ни подключения к БД, ни защиты от ошибок. Только канва.
Ответить с цитированием