Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как построить дерево объектов? / 5 сообщений из 5, страница 1 из 1
13.02.2019, 20:09
    #39773570
FIL23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как построить дерево объектов?
Добрых суток,

Может у кого есть красивая функция построения дерева или что то в этом роде.

Суть такова имеется информация в БД об объектах, в которой указан ID родитель объекта.

Т.е. предположим у нас есть вот такого вида дерево

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
Объект 1
  |
  |--------Объект 2
  |               |
  |               ----------Объект 3
  |
  |---------Объект 4
Объект 5



То информация в БД будет примерно такого вида


Код: powershell
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
-----------------------------------
ID   |  ID_PARENT        |  NAME_ |
-----------------------------------
1    |      0            |Объект 1|
-----------------------------------
2    |      1            |Объект 2|
-----------------------------------
3    |      2            |Объект 3|
-----------------------------------
4    |      1            |Объект 4|
-----------------------------------
5    |      0            |Объект 5|
-----------------------------------



У меня есть самописная функция, но может есть что- то "элегантней"? (предоставлю функцию для TreeView как пример может кому понадобится)

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
//-----------------------------------
 type
  TRecordIBQuery = class
    ID      :integer;
    ID_PARENT :integer;
    TEXT    :string;
    ID_ICO  :integer;
  end;

procedure Creat_Items_To_Treeviwe(perIBQuery :TIBQuery; perTreeView :TTreeView; perTreeName:string);
var
  Node :TTreeNode;
  recIB :TRecordIBQuery;
  Lost :TObjectList;

  function GetRecIB():TRecordIBQuery;
  begin
    result:=TRecordIBQuery.Create;
    result.ID:=perIBQuery.FieldByName('ID').AsInteger;
    result.ID_PARENT:=perIBQuery.FieldByName('ID_PARENT').AsInteger;
    result.TEXT:=trim(perIBQuery.FieldByName('TEXT').AsString);
    result.ID_ICO:=perIBQuery.FieldByName('ID_ICO').AsInteger;
  end;

  function FindParent(idPar :integer):TTreeNode;                                //поиск родителя
  var i :integer;
  begin
    for i:=0 to perTreeView.Items.Count-1 do begin
      result:=perTreeView.Items[i];
      if integer(result.Data) = idPar then begin
        exit;
      end;
    end;
    result:=nil;
  end;

  procedure DoLost();
  var i :integer;
  begin
    for i:=Lost.Count-1 downto 0 do begin
      recIB:=TRecordIBQuery(Lost[i]);
      Node:=FindParent(recIB.ID_PARENT); //родитель уже создан?
      if Node <> nil then begin
        Node:=perTreeView.Items.AddChildObject(Node, recIB.TEXT, pointer(recIB.ID));
        Node.ImageIndex:=recIB.ID_ICO;
        Node.SelectedIndex:=recIB.ID_ICO;
        Lost.Delete(i); //удаляем из списка потерянных, объект recIB освобождается автоматом
      end;
    end;
  end;

begin
  Lost:=TObjectList.Create;                                                     //создаем список для потерянных узлов
  try
    perIBQuery.Active:=false;                                                   //деактивируем запрос
    perIBQuery.SQL.Text:='select * from '+perTreeName+' ORDER BY ID_PARENT, POSITION_ ASC';             //запрос вся таблица дерева по порядку с первого номера
    perIBQuery.Active:=true;                                                    //активируем запрос
    while not perIBQuery.Eof do begin                                           //пошли в цыкл по запросу
      recIB:=GetRecIB();                                                        //копируем данные записи в вспомогательный класс , который создается в функции
      if recIB.ID_PARENT = 0 then begin                                         //если запись не имеет родителя то это корень , т.е. самый главный родитель
        Node:=perTreeView.Items.AddObject(nil, recIB.TEXT, pointer(recIB.ID));  //пишем его в дерево присваивая порядковый номер в  pointer
        Node.ImageIndex:=recIB.ID_ICO;
        Node.SelectedIndex:=recIB.ID_ICO;
        recIB.Free;                                                             //не забываем освобождать память от уже ненужного объекта
      end else begin                                                            //родитель должен быть
        Node:=FindParent(recIB.ID_PARENT);                                      //родитель уже создан?
        if Node = nil then begin                                                //не нашли
          Lost.Add(recIB);                                                      //запоминаем данные
        end else begin                                                          //цепляемся к родителю
          Node:=perTreeView.Items.AddChildObject(Node, recIB.TEXT, pointer(recIB.ID));
          Node.ImageIndex:=recIB.ID_ICO;
          Node.SelectedIndex:=recIB.ID_ICO;
          recIB.Free;                                                           //не забываем освобождать память от уже ненужного объекта
        end;
      end;
      perIBQuery.Next;
    end;
    //окучиваем потерянные объекты
    while Lost.Count > 0 do DoLost();
  finally
    Lost.Free;
  end;
end;


...
Рейтинг: 0 / 0
13.02.2019, 20:28
    #39773585
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как построить дерево объектов?
FIL23,

Таких полно. Обычно, оформленных в виде удобных компонетов. Тебе куда его потом?
...
Рейтинг: 0 / 0
13.02.2019, 20:36
    #39773590
FIL23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как построить дерево объектов?
Vlad FТебе куда его потом?

Мне надо создавать динамически объект на форме. А там как известно родитель может быть не только форма но и компонент.
...
Рейтинг: 0 / 0
13.02.2019, 20:43
    #39773592
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как построить дерево объектов?
FIL23,

Динамически, так динамически. Но почему обязательно свой велосипед?
А если даже свой, то зачем с ним в местный калашный ряд?
Если свое все-таки не нравится/смущает, то так и проси
посоветовать что-то готовое/опробованное.
...
Рейтинг: 0 / 0
14.02.2019, 08:51
    #39773682
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как построить дерево объектов?
FIL23,

Основной минус вашей штуки - она грузит ВСЁ

почитайте про Дерево каталогов NESTED SETS
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как построить дерево объектов? / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]