• 0
x11

Цикл по TTreeView обходит не все уровни

Вопрос

Почему этот цикл "видит" только первый уровень дерева?

Тогда как правильно организовать поиск нужного TreeViewItem`а по всем узлам, по всему дереву?

 


function TfmTree.FindItemByIndex(id_parent: Integer): TTreeViewItem;
var
  i: Integer;
begin
  Result := nil;
  for i:= 0 to Pred(TreeView1.Count) do
   if TreeView1.Items[i].Tag = id_parent then
    begin
     Result := TreeView1.Items[i];
     break;
    end;
end;                          

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

22 ответа на этот вопрос

  • 0

Я так понял, у TTreeView нет методов поиска узлов :(

Нужно городить свой огород с рекурсией.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Почему GlobalCount всегда возвращает количество корневых узлов?

 

function TfmTree.ItemByTag(id: integer): TTreeViewItem;
var
  Item: TTreeViewItem;
  I: Integer;
begin
  Result := nil;
  for I := 0 to Pred(TreeView1.GlobalCount) do
  begin
    Item := TreeView1.ItemByGlobalIndex(I);
    if Item.Tag = id then
      Exit(Item);
  end;
end;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Тут в чем затык. Есть цикл по таблице для заполнения дерева. Получается, что при каждой итерации нужно вызывать ExpandAll.

 

 

Изменено пользователем x11

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Я знаю, что рациональнее заполнять дерево по мере раскрытия узлов. Но нужно иметь возможность поиска по тексту узла. А пока не прогрузишь всё дерево, искать по нему нет возможности.

Поэтому нужно грузить всё дерево целиком.

А у стандартного дерева FMX отсутствуют такие свойства, как в других DBTree-деревьях. Где достаточно указать три основных поля из таблицы: id, parent, name. Не говоря уже о других служебных полях.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Посмотрите на метод http://docwiki.embarcadero.com/Libraries/Seattle/en/FMX.Controls.TControl.EnumControls он создан для удобного обхода по всему дереву контролов. Просто проверяйте класс входного параметра и делайте ваш поиск.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
TreeView.ItemByGlobalIndex

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
Только что, Равиль Зарипов (ZuBy) сказал:

работает только с раскрытым списком

Ну, чукча не читатель, чукча писатель :)

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
7 часов назад, Brovin Yaroslav сказал:

Посмотрите на метод http://docwiki.embarcadero.com/Libraries/Seattle/en/FMX.Controls.TControl.EnumControls он создан для удобного обхода по всему дереву контролов. Просто проверяйте класс входного параметра и делайте ваш поиск.

 

 

Примеров, случайно нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
Только что, x11 сказал:

Примеров, случайно нет?

Так на странице документации есть пример.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

просто там что-то страшное и на delphi не похожее

Panel1.EnumControls(function (Control: TControl): TEnumControlsResult

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

я бы сказал, что непривычное для Delphi

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Придется прокачать скилы. Я за вас делфи не могу выучить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Как правило, Delphi - это же что-то красивое и изящное, извините за оффтоп :)

Изменено пользователем x11

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Пока непонятно, что такое ListOfVisibleControls. Это список мой? Я сам должен где-то объявить и создать? Какого типа? Это глобальный объект или локальный?

Изменено пользователем x11

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Получается, что метод GlobalCount неправильно назван и вводит программиста в заблуждение. Его бы правильно назвать - VisibleCount или ExpandedCount.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

вот пример с EnumControls и ItemByGlobalIndex

никаких проверок не писал, а они нужны в реальном проекте

TreeViewSearch.zip

x11 понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Спасибо, ушёл, изучать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Спрошу в порядке оффтопика: почему у вас так причудливо обозначена верхняя граница цикла? Зачем это Pred(TreeView1.Count)? Чем хуже простое  TreeView1.Count-1 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

не знаю, новшества языка использую :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: david_yusupov
      Точнее, как работает наследование.
        TNodeItem = class(TTreeViewItem)   public     constructor Create(AOwner: TComponent); override;     destructor Destroy; override;   end;     TNodeItem2 = class(TNodeItem)   public     constructor Create(AOwner: TComponent); override;     destructor Destroy; override;   end; реализация { TNodeItem } constructor TNodeItem.Create(AOwner: TComponent); begin   inherited Create(AOwner); end; destructor TNodeItem.Destroy; begin   inherited; end; { TNodeItem2 } constructor TNodeItem2.Create(AOwner: TComponent); begin   inherited Create(AOwner); end; destructor TNodeItem2.Destroy; begin   inherited; end; // Вот самое интересное, не много не понятно почему так
      procedure TForm1.Button2Click(Sender: TObject); var   xTree: TTreeViewItem; begin   // Тут все работает   xTree := TTreeViewItem.Create(nil);   xTree.Text := 'Тест2';   xTree.Parent := TreeView1; end; procedure TForm1.Button3Click(Sender: TObject); var   xTree: TNodeItem; begin   // И тут все работает   xTree := TNodeItem.Create(nil);   xTree.Text := 'Тест3';   xTree.Parent := TreeView1; end; procedure TForm1.Button4Click(Sender: TObject); var   xTree: TNodeItem2; begin   // А вот тут не работает, узел добавляется, а текста нет.   xTree := TNodeItem2.Create(nil);   xTree.Text := 'Тест4';   xTree.Parent := TreeView1; end;  
    • Автор: golomeen
      Поэкспериментировал и нашел простейший случай - узел и в нем два листа.
      Алгоритм следующий (упрощенно)
      каждый лист показывает пару key=value
      при клике в узел остается только key= и показывается листвью с выбором value. Затем мы получаем грубо key=new value (хотя не обязательно)
      После такой операции вы обязательно получаем то что 2 листа меняются местами
       
      С узлом ничего не происходит ни программно ни фактически
       
      В более сложных случаях тоже шевеление наблюдается, но я его не изучал подробно
    • Автор: slava_d2000
      Добрый день!
       
      Прошу подсказать как программно выделить элемент дерева.
    • Автор: Dzuyba
      Мне требуется динамически добавлять и удалять элементы дерева. И чтобы лучше понять как работать с FMX.TreeView.TTreeView я написал простой тестовый примерчик и который не могу заставить работать. Приложение вообще падает. Может подскажите где я ошибаюсь.
       
      Описание тестового примера
      Нужно когда пользователь разворачивает (Expand) элементы дерева, я хочу удалять все дочерние элементы затем добавлять новые дочерние элементы и потом уже пускай родительский TreeViewItem раскрывается (Expand) для показа новых дочерних элементов.
       
      Для эмуляции OnExpand и OnCollapse пользуюсь способом, описанным тут: Как можно реализовать в TTreeView события OnExpand и OnCollapse?
       
      Тест кейс
      Достаточно создать корневой элемент, В него добавит дочерний элемент  Потом раскрывать (Expand) корневой элемент. И приложение падает. Когда происходит ошибка
      Добавляешь корневой элемент дерева, потом в него дочерний элемент. Пытаешься развернуть (Expand) корневой элемент (кликая мышкой по плюсику) и приложение падает.
       
      Тестовый проект: Test_Tree.zip
    • Автор: Dzuyba
      Как можно реализовать данное событие а лучше целых 2 события OnExpand и OnCollapsed
    • Автор: fil23
      Такая задача.
      Хочу создать некоторое дерево вида:
      Корень   -потомок   -потомок Корень   -потомок   -потомок    -потомок Корень   -потомок     -потомок       -потомок и записать данную структуру в БД (FB). А потом в обратную сторону - из данных в БД, программно создать эту же структуру.
      Но как в VCL не нашел Nodes, и absoluteindex. Так сказать не на что опереться в числовом представлении.
      Попробовал использовать Globalindex - вышла неудача , он выдает "правильный" результат, т.е. какой он по счету только когда все ветви полностью раскрыты.
      Думаю ладно, если тебе надо чтобы были все ветки раскрыты, пусть будут, решил использовать ExpandetALL а потом уже находить Globalindex, но увы опять неудача, он просто не разворачивает ветки (указатели меняют расположение) , а данные так и лежат свернутые. Нажимаешь на любую ветку и данные разворачиваются. Но код уже отработал и выдал не правильный индекс (такой как при свернутых ветках).
       
       
      Проблема - в каком виде представлять объекты? хотелось бы в числовом по уникальному ID 
      Как их находить?
       
      Спасибо.
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу