Перейти к содержанию
  • 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;                          

 

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


Ссылка на сообщение

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

  • 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
10 минут назад, kami сказал:

TreeView.ItemByGlobalIndex

 

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

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


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

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

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

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

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


Ссылка на сообщение
  • 0
7 часов назад, Brovin Yaroslav сказал:

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

 

 

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

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


Ссылка на сообщение
  • 0

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

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

 

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


Ссылка на сообщение
  • 0

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

Отредактировал x11

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


Ссылка на сообщение
  • 0

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

Отредактировал x11

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


Ссылка на сообщение
  • 0

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

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


Ссылка на сообщение
  • 0

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

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

TreeViewSearch.zip

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


Ссылка на сообщение
  • 0

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

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


Ссылка на сообщение
  • 0

А чем не нравится рекурсия? я обычно через рекурсию обхожу по дереву, всего 2 функции, при желании в 1 можно.

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


Ссылка на сообщение

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

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

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

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

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

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

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

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


  • Похожий контент

    • От x11
      function OnlyDec(const s: String): string; Var ch: char; i: integer; begin for i := 0 to s.Length do if CharInSet(s[i], ['0'..'9']) then result := result + s[i]; или for i := low(s) to High(s) do if CharInSet(s[i], ['0'..'9']) then result := result + s[i]; или for ch in s do if ch in ['0'..'9'] then result := result + ch; или for ch in s do if CharInSet(ch, ['0'..'9']) then result := result + ch; end; Почитал http://docwiki.embarcadero.com/RADStudio/Tokyo/en/String_Types_(Delphi) но до конца не понял.
      Как всё-таки более правильно сделать цикл по строке?
      Я склоняюсь к последнему варианту.
    • От x11
      Может кому пригодится.
      Немножко запутался я, т.к. в FMX почти любая визуальная компонента может быть контейнером для другой компоненты.
       
      Рабочий код.
      function GetPathFromNode(AItem: TTreeViewItem): String; begin if AItem = nil then exit('ничего не выбрано'); while Assigned(AItem) and (AItem is TTreeViewItem) do begin Result := AItem.Text + '/' + Result; AItem := TTreeViewItem(AItem.ParentItem); end; Delete(Result, Length(Result), 1); end;  
      проблема была у меня AItem.Parent
      а правильно - AItem.ParentItem
    • От 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 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

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