Thema: Delphi TreeView bestücken

Einzelnen Beitrag anzeigen

QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
1.944 Beiträge
 
Delphi 12 Athens
 
#5

AW: TreeView bestücken

  Alt 4. Apr 2023, 13:42
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;
Andreas
Monads? Wtf are Monads?

Geändert von QuickAndDirty ( 4. Apr 2023 um 14:07 Uhr)
  Mit Zitat antworten Zitat