Как я могу скопировать поддерево из одного TTreeView в другой?

#delphi #loops #treeview #iteration

#delphi #циклы #просмотр дерева #итерация

Вопрос:

Я хочу скопировать выбранный узел и всех его потомков из одного TTreeView в другой.

Каков наилучший, наиболее эффективный способ добиться этого?

Комментарии:

1. Я не совсем понимаю, что вы пытаетесь сделать … если вам нужны только дочерние узлы выбранного, никто не может быть его родителем или самим прародителем!… переосмыслите способ выражения того, что вам нужно, и измените формулировку своего поста!

Ответ №1:

Проще всего сделать это рекурсивно, что-то вроде этого:

 procedure WalkChildren(Node: TTreeNode; List: TList<TTreeNode>);
var
  i: Integer;
begin
  List.Add(Node);
  for i := 0 to Node.Count-1 do begin
    WalkChildren(Node[i], List);
  end;
end;
  

Назовите это следующим образом:

 List := TList<TTreeNode>.Create;
WalkChildren(Root, List);
  

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

Теперь, когда мы можем обойти одно дерево, пришло время обойти два дерева в тандеме.

 procedure CopySubTree(Src, DestParent: TTreeNode; DestNodes: TTreeNodes);
var
  i: Integer;
  Dest: TTreeNode;
begin
  Dest := DestNodes.AddChild(DestParent, Src.Text);
  //copy other parameters from Src to Dest as you please
  for i := 0 to Src.Count-1 do begin
    CopySubTree(Src[i], Dest, DestNodes);
  end;
end;
  

Вы можете назвать это следующим образом:

 CopySubTree(SrcTree.Selected, nil, DestTree.Items);
  

Комментарии:

1. Извините, Дэвид, возможно, мой вопрос был не совсем ясен. Я приложил скриншот, чтобы показать именно то, что я ищу. Также в вашем коде мне пришлось изменить Node. Элементы [i] в узел [i], хотя, если мой вопрос был неправильно понят, эта процедура больше не понадобится.

2. @David время истекает. 😉

3. Это работает идеально, спасибо, Дэвид, я принял ваш ответ. Извините за первоначальную путаницу, хотя ваш первый фрагмент кода будет полезен в других ситуациях

4. Ого! Я потратил слишком много времени на написание своего ответа и в итоге продублировал ваш.

5. @David: 1 только за выражение «ходить вдвоем в тандеме». 😉 Серьезно, хороший ответ.