Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как найти реальный индекс узла TTreeViewItem дерева?


fil23

Вопрос

Такая задача.

Хочу создать некоторое дерево вида:

Корень
  -потомок
  -потомок
Корень
  -потомок
  -потомок
   -потомок
Корень
  -потомок
    -потомок
      -потомок

и записать данную структуру в БД (FB). А потом в обратную сторону - из данных в БД, программно создать эту же структуру.

Но как в VCL не нашел Nodes, и absoluteindex. Так сказать не на что опереться в числовом представлении.

Попробовал использовать Globalindex - вышла неудача , он выдает "правильный" результат, т.е. какой он по счету только когда все ветви полностью раскрыты.

Думаю ладно, если тебе надо чтобы были все ветки раскрыты, пусть будут, решил использовать ExpandetALL а потом уже находить Globalindex, но увы опять неудача, он просто не разворачивает ветки (указатели меняют расположение) , а данные так и лежат свернутые. Нажимаешь на любую ветку и данные разворачиваются. Но код уже отработал и выдал не правильный индекс (такой как при свернутых ветках).

 

 

Проблема - в каком виде представлять объекты? хотелось бы в числовом по уникальному ID 

Как их находить?

 

Спасибо.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Коллега, вы совершенно не верно подходите к решению задачи. TreeView - это представление, а база данных - это модель. Потому построение дерева должно опираться на данных в БД, а не наоборот. 

Дерево в базе хранят обычно в одной таблице такой структуры:

id - id объекта

parent - id родителя

text - наименование

 

например ваша структура в БД будет примерно так выглядеть:

1, null, Родитель 1

   2, 1, Потомок 1-1

   3, 1, Потомок 1-1

4, null, Родитель 2

   5, 4, Потомок 2-1

   6, 4, Потомок 2-2

      7, 6, Потомок 2-3  - обратите внимание - потомок потомка

и т.д.

 

Для того что бы связать запись БД и Item в дереве используйте свойство Tag. Это просто и удобно. 

Как строить дерево:

1. Самый плохой способ  - при запуске программы, из БД считывается все данные и по ним строится полное дерево. При добавлении/удалении записи все повторяем - перечитываем полное дерево. Таким способом лучше не делать. За такой метод бьют ногами не похвалят. Причем и пользователи (за тормоза программы) и админ сервера БД (за нагрузку на сервер).

 

2. Этот способ немного лучше -  при запуске мы точно также считываем полное дерево из БД. Но при добавлении записей, мы добавляем только конкретный Item в дерево и его Tag присваиваем ID который назначил сервер при создании записи в БД. Но тут все еще есть недостаток - полное построение дерева - если записей много, то может занимать много времени.

 

3. Самый лучший способ - при запуске считываются только корневые записи (parent = null). А остальные подгружаются по мере необходимости. Когда пользователь разворачивает ветку, то из БД получаем все записи parent = Selected.Tag и добавляем детей к этой ветке.  Добавление новых записей так же как в способе 2.

 

Рекомендую вам использовать именно способ 3. Во первых он самый быстрый, во вторых считывание из БД наиболее простое. Иначе вам без рекурсивных хранимых процедур будет сделать полное чтение дерево очень сложно.  Здесь же можно все выбирать простыми запросами. 

Еще пара советов:

если данных много и по дереву ходят много - то постепенно программа подгрузит много веток и это может занимать много памяти, что может привести к тормозам. Потому при сворачивании ветки, лучше всех детей удалять. 

Когда ветка не имеет детей, то у нее нет слева стрелочки для разворачивания. Потому возникает вопрос - как же тогда развернуть ветку, чтобы подгрузить детей? Все просто. Надо создать одного фейкового ребенка. Т.е. просто Item-пустышку не связанную с БД. А когда ветку разворачивают, то первым делом надо пустышку удалить. Потом считать БД. Естественно при сворачивании делаем наоборот - сначала удаляем все реальные Item-ы, а потом вновь добавляем пустышку.

Вот как то так.

Изменено пользователем DirtyBorov
Ссылка на комментарий
  • 0

Если есть уникальное текстовое поле ищи itemByText, но самый правильный вариант в случае когда хранилище данных FB это 3. описанный выше. Если хранилище например XML файл, то уже не факт, что не нужно строить сразу.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...