Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TreeView bestücken (https://www.delphipraxis.net/212795-treeview-bestuecken.html)

d.adams 2. Apr 2023 15:27


TreeView bestücken
 
Hallo,

ich muss die Struktur eines TreeView exportieren und an anderer Stelle wieder einlesen. Woran an der Struktur kann ich erkennen was ein aufklappbarer Knoten ist (Level = 0 ?) und welche Unteritems daran hängen?

Zudem die Reihenfolder der Konten und die der dazugehörigen Sub_items?

Gruß
Heiko

himitsu 2. Apr 2023 17:04

AW: TreeView bestücken
 
Level ist natürlich die Ebene des jeweiligen Items.
0 ganz oben, 1 die ersten UnterItems, 2 die UnterUnterItems usw.

Items, sowie auch SubItems, liegen jeweils im Item.

Zusammenklappen heißt Collapse und Aufklappen Expand. :zwinker:




Delphi-Quellcode:
  TreeView1.Items.Count
  TreeView1.Items[i] //  TreeView1.Items.Item[i]

  TreeView1.Items[i].Collapse;
  TreeView1.Items[i].Expand;
  TreeView1.Items[i].Expanded // was es ist

  TreeView1.Items[i].Count
  TreeView1.Items[i][j] //   TreeView1.Items.Item[i].Item[j]
  TreeView1.Items[i][j].Expanded

  TreeView1.Items[i][j].Count
  TreeView1.Items[i][j][k] //   TreeView1.Items.Item[i].Item[j].Item[k]
  TreeView1.Items[i][j][k].Expanded
  ...

Delbor 3. Apr 2023 10:56

AW: TreeView bestücken
 
Hi d.adams

Ein Ausschnitt aus der Prozedur AddNewNode, die dem Treeview einen Ordner- oder Dateiknoten hinzufügt:

Delphi-Quellcode:
begin
  Node := TVFilesExplorer.Items.AddChild(ParentNode, aCaption);
Das fügt einem bekannten Knoten () einen neuen hinzu.
Delphi-Quellcode:
  if aIsdirectory then
  begin
    Node.ImageIndex := 1;
    Node.SelectedIndex := 1;
Die Abfrage auf IsDirectory wurde so von mir hinzugefügt. Das Original von DeddyH prüfte hier auf Node.hasChildren - Dateien haben keine Children (untergeordnete Dateien).

Gruss
Delbor

himitsu 3. Apr 2023 12:38

AW: TreeView bestücken
 
Zitat:

Zitat von Delbor (Beitrag 1520617)
Die Abfrage auf IsDirectory wurde so von mir hinzugefügt. Das Original von DeddyH prüfte hier auf Node.hasChildren - Dateien haben keine Children (untergeordnete Dateien).

Leere Verzeichnisse aber auch. :angle:

QuickAndDirty 4. Apr 2023 12:42

AW: TreeView bestücken
 
Wichtig ist das du bei größeren TTreeNodes niemals über "Items[i]" iterierst! sonder immer mit GetFirstSibling, GetNexSibling und GetFirstChild im DFS stil den baum durchläufst!
Auch wiederholtes abfragen von "AbsoluteIndex" sollte man in großen Bäumen nicht durchführen, wenn es nicht sien muss, denn das führt auch zu einem ewigen durch den Baum hangeln....wenn der Baum sehr groß ist.
Am besten man schreibst sich einen Iterator für den Baum um Suchen oder Massenhafte Änderungen oder Kopien von oder an Baumknoten durchzuführen.

Ich hatte mal einen TTreeView immer wieder in einen Cache kopiert, über Items[i].... und daraus wieder hergestellt...Daraus gelernt.. auch "Assign" iteriert einfach über die Items[i]
und dann dauert es ewig bis 2500 Nodes kopiert wurden, weil die getItem metode hinter Items[i] immer von neuem wieder anfängt das I-te Item abzuzählen...
Intern werden dann 3126250 Knoten abgelaufen um 2500 Knoten zu iterieren....
Also Kein Assign, kein AbsoluteIndex, Kein Items.count und kein Items[i] benutzen.
Einen DFS-Iterator benutzen!
Oder einfach nur kleine Bäume verwenden...

Sowas in der art
Delphi-Quellcode:
type
TTreeNodeWorkFunction = reference to Function(aTreeNode:TTreeNode): TTreeNode;
Function ForEachItem(Nodes:TTreenodes; aWorkFunction:TTreeNodeWorkFunction; const LevelMaxFilter:Integer = -1  ):TTreenode;
var currentNode, nextNode:TTreeNode;
Begin
  Function ForThisNode(aNode:TTreenode; aWorkFunction:TTreeNodeWorkFunction; const LevelMaxFilter:Integer = -1):TTreeNode;
  var currentNode, nextNode:TTreeNode;                                                                
  Begin                                                                                                
    Result := nil;                                                                                    
    if (LevelMaxFilter = -1) or (Anode.Level < LevelMaxFilter ) then                                  
    Begin                                                                                              
      currentNode := aNode.getFirstChild;                                                              
      While assigned(CurrentNode) Do                                                                  
      Begin                                                                                            
        nextNode := currentNode.getNextSibling;//NextNode Ermitteln für den fall das CurrentNode gelöscht wird
        result := ForThisNode(currentNode,aWorkFunction,LevelMaxFilter);                                
        if assigned(Result) then                                                                        
          nextNode := nil; // Bei Suche direkt abbrechen                                                
        CurrentNode := NextNode;//Navigation zum Sibling                                                
      End;                                                                                              
    end;                                                                                              
    if not assigned(Result) then                                                                      
      Result := aWorkFunction(aNode);                                                                  
  End;  
Begin                                                                                              
  Result := nil;                                                                                      
  currentNode := Nodes.GetFirstNode;                                                                  
  While assigned(currentNode) do // für alle wurzeln....                                                                      
  Begin                                                                                                
    nextNode := currentNode.getNextSibling;//NextNode Ermitteln für den fall das CurrentNode gelöscht wird
    Result := ForThisNode(currentNode,aWorkFunction,LevelMaxFilter);                                  
    if assigned(Result) then                                                                          
      nextNode := nil; // Bei Suche direkt abbrechen                                                  
    CurrentNode := NextNode;//Navigation zum Sibling                                                  
  End;  
end;

d.adams 7. Apr 2023 11:35

AW: TreeView bestücken
 
Danke für die Hinweise, ich sehe mal wie weit ich damit komme

gruß
Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz