![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Добрый день, очень прошу помощи! Помогите, очень срочно, мучаюсь два дня! На Делфи пишу впервые, просмотрела много тем, так и не нашла своей ошибки. Пишу на Delphi7.
Задача: Заполнить рекурсивно дерево TreeView из БД FireBird, данные заполняются из таблицы Catalogi, где поля id_cat, name, opisanie, id_rod_cat. SQL запрос в IBQuery_output: select * from CATALOGI where CATALOGI.ID_ROD_CAT= : parent; Ошибка в следующем: заполняю я в обратном порядке, рекурсивно, но заполняет только последний подкаталог, а на выше уровня подкаталог не поднимается . Текст программы: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons, IBDatabase, DB, IBQuery, IBCustomDataSet, IBTable, ComCtrls, Menus, Grids, DBGrids; type TInfoC = class id: integer; id_parent:integer; NameC : string; end; PTInfoC = ^TInfoC; TForm1 = class(TForm) TreeView1: TTreeView; IBTable1: TIBTable; IBQuery_output: TIBQuery; IBDatabase1: TIBDatabase; DataSource_output: TDataSource; IBTransaction1: TIBTransaction; IBQuery_new_cat: TIBQuery; DataSource_new_cat: TDataSource; SpeedButton1: TSpeedButton; SpeedButton2: TSpeedButton; DBGrid1: TDBGrid; procedure FormCreate(Sender: TObject); //procedure SpeedButton1Click(Sender: TObject); procedure TreeBuild(T:TTreeNode); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var InfoC: TInfoC; U: TInfoC; Catalog: TTreeNode; dop:integer; sss:string; begin IBQuery_output.Active:=true; IBQuery_output.Params.ParamByName('parent').Value:=0; IBQuery_output.Close; IBQuery_output.Open; IBQuery_output.Active:=true; DBGrid1.Repaint(); DBGrid1.DataSource.DataSet.First; while not DataSource_output.DataSet.Eof do begin //InfoC.id:=0; if ((DBGrid1.Columns[0].Field.AsInteger=1 )and (DBGrid1.Columns[3].Field.AsInteger=0)) then begin //Catalog:=TreeView1.Items.Add(nil,DBGrid1.Columns[1].Field.Text); //if (InfoC<>nil) then //begin InfoC:=TInfoC.Create; InfoC.id:=DBGrid1.Columns[0].Field.AsInteger ; InfoC.NameC:=DBGrid1.Columns[1].Field.AsString; InfoC.id_parent:=0; Catalog:=TreeView1.Items.AddObject(nil,DBGrid1.Columns[1].Field.Text, @InfoC); //sss := PTInfoC(Catalog.Data)^.NameC; //ShowMessage(sss) ; end; DataSource_output.DataSet.Next; end; TreeBuild(Catalog); // //ïåðåõîä íà ñëåäóþùóþ çàïèñü â òàáëèöå // öèêë end; procedure TForm1.TreeBuild( T: TTreeNode); var InfoC :TInfoC; ttt:^TInfoC; NewInfoC :array of TInfoC; Catalogs, C : TTreeNode; dop,i,parent,countlist:integer; index_first, index_last: integer; sss:string; cT:TTreeNode; begin parent := (PTInfoC(T.data))^.id; IBQuery_output.Active:=false; IBQuery_output.Params.ParamByName('parent').AsInteger:=parent; IBQuery_output.Close; IBQuery_output.Open; IBQuery_output.Active:=true; DBGrid1.Repaint(); if IBQuery_output.RecordCount>0 then begin SetLength(NewInfoC, IBQuery_output.RecordCount); i:=0; while not DataSource_output.DataSet.Eof do begin if ( DBGrid1.Columns[3].Field.AsInteger=parent) then begin NewInfoC[i]:=TInfoC.Create; NewInfoC[i].id:=DBGrid1.Columns[0].Field.AsInteger ; NewInfoC[i].NameC:=DBGrid1.Columns[1].Field.AsString; NewInfoC[i].id_parent:=parent; TreeView1.Items.AddChildObject(T,DBGrid1.Columns[1].Field.Text, @NewInfoC[i]) ; i:=i+1; end ; DataSource_output.DataSet.Next; end; //while cT:= (T.getFirstChild); while cT<>nil do begin // TreeBuild(cT); cT:=cT.getNextSibling; end; end; //if end; end. Последний раз редактировалось M.A.D.M.A.N., 29.05.2015 в 08:04. |
#2
|
|||
|
|||
![]() А точно надо рекурсивно?
Вообще, я обычно в таком случае делаю LazyLoad. Т.е. изначально заполняется только верхний уровень (where parent is null), а при раскрытии узла подгружается только этот узел. Фокус в том, что когда создаешь узел ему надо создать фейкового ребенка, что бы была возможность этот узел раскрывать. При раскрытии узла этот подузел удаляется и создаются нормальные, загруженные из БД. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
mariyaprigoda (30.05.2015)
|
#3
|
|||
|
|||
![]() Цитата:
|
#4
|
|||
|
|||
![]() Готового примера под рукой нет.
Тебе нужно событие OnExpanding, в еотором надо почистить текущий нод и создать новые, считав из БД. |