2012-12-26 18 views
6

Ich habe eine Baumansicht, die bereits mit Dateien/Ordnern aus einer anderen Prozedur gefüllt ist. Ich möchte nacheinander durch die Elemente in der Baumansicht iterieren, wobei die Reihenfolge von oben nach unten genau ist. Im Gegensatz zu einer normalen Liste kann ich dafür aber nicht einfach eine einfache for-Anweisung verwenden. Ich muss in jeden Knoten usw. gehen.Wiederhole rekursiv über Knoten in einer Baumansicht?

Wie mache ich das? Ich hoffe, es gibt einen Weg, wie ich es machen kann, ohne eine rekursive Prozedur auszuführen. Wenn ich diese Elemente durchlaufe, interessiert mich nicht unbedingt der Eltern- oder Kindknoten des aktuell fokussierten Elements. Ich muss nur in der Lage sein, die Data Eigenschaft jedes Knotens zu lesen, während ich sie passiere, sowie die aktuelle in der Baumansicht markieren, während ich es durchlaufe. Für jedes Element in dieser Baumansicht führe ich einige Arbeiten aus und möchte dem Benutzer visuell anzeigen, welches gerade während dieses Vorgangs ausgewählt ist.

+0

"Ich kann nicht nur eine einfache Anweisung für diese verwenden" <- Ich habe Probleme zu verstehen, warum? Sie sollten eine rekursive Funktion/Prozedur mit einer ** for ** -Schleife in ihrem Körper verwenden, nach der ** for-Schleife ** handeln Sie mit der Node.Data-Eigenschaft und der Aufrufer geht zum nächsten Knoten und so weiter ... – ComputerSaysNo

+1

Ich sagte, dass ich dafür keine einfache ** for ** -Anweisung verwenden kann, weil es in einer Baumansicht keinen Objektindex oder eine Gesamtzahl von Knoten gibt. –

+0

Der ganze Grund, den ich stelle, ist, weil ich versuche, diese Prozedur rekursiv aufzurufen, ich hätte lieber eine gerade 0..MAX-1-Schleife ohne Rekursion, aber ich glaube nicht, dass es möglich ist und ich möchte sichergehen. –

Antwort

16

In der Tat können Sie eine for Schleife verwenden.

var 
    Node: TTreeNode; 
.... 
for Node in TreeView.Items do 
    DoSomething(Node); 

Dieser syntaktischer Zucker für:

for i := 0 to TreeView.Items.Count-1 do 
    DoSomething(TreeView.Items[i]); 

In Bezug auf die Lesbarkeit würde ich die for/in Schleife empfehlen.

In älteren Delphi-Versionen, die den Knoten-Iterator nicht unterstützen, empfiehlt es sich, dies mit einer while-Schleife zu tun.

Node := TreeView.Items.GetFirstNode; 
while Assigned(Node) do 
begin 
    DoSomething(Node); 
    Node := Node.GetNext; 
end; 

Ich erwarte, dass es andere Möglichkeiten gibt, es zu tun. Das sind die einzigen, die ich kenne!


LU RD macht die interessante Beobachtung, dass die documentation Zustände:

Zugriff auf Baumansicht Artikel von Index zeitintensiv sein kann, vor allem, wenn der Baumansicht viele Elemente enthält. Versuchen Sie für eine optimale Leistung, Ihre Anwendung so zu entwerfen, dass sie so wenig Abhängigkeiten vom Objektindex der Strukturansicht aufweist wie möglich.

Das ist ziemlich wahr. Für einen wahlfreien Zugriff muss der Code den Baum durchlaufen, beginnend an der Wurzel, bis der Knoten sich befindet.

Es gibt jedoch eine Optimierung für den sequentiellen Zugriff. Der Delphi-Baumansichts-Wrapper merkt sich den Index des letzten Knotens, der sich nach dem Index befindet. Wenn Sie das nächste Mal nach einem Knoten mit einem Index suchen, der nicht mehr als ein anderer als der zwischengespeicherte Knoten ist, kann der erforderliche Knoten schnell zurückgegeben werden. Dies ist in TTreeNodes.GetNodeFromIndex implementiert.

+0

NICE und ich hätten das nie für möglich gehalten. –

+0

+1 wusste nie, dass es möglich ist, alle Artikel in einer Schleife zu durchlaufen ... – ComputerSaysNo

+0

+1 nette Abrundung der ersten Post ... – bummi

3
var 
i:Integer; 
begin 
    for I := 0 to tv.Items.Count - 1 do 
     begin 
     Listbox1.Items.Add(tv.Items[i].Text +' SubItems: ' + IntToStr(tv.Items[i].Count)) 
     end; 

end; 
+0

Dies tut nur die erste Ebene der Hierarchie, nicht alle Unterpunkte. –

+3

@Jerry Nein, das zählt sie alle –

+0

... Ich bin dann verwirrt, Entschuldigung für voreilige Schlussfolgerungen. –

Verwandte Themen