Autor Beitrag
daywalker0086
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243


Delphi 2005 Architect
BeitragVerfasst: Di 15.03.11 18:17 
Nochmal ich, beschäftige mich nach erfolgreicher Installation der VirtualTreeview Komponente mit der hierarchischen Darstellung.
In den ganzen Tutorials werden immer Records für die Daten Verwendet aber ich habe für die einzelnen Nodes ein Array welches folgendermaßen aufgebaut ist:
Hauptgruppe| Mittelgruppen |Gruppenadresse| Bezeichnung
1 | 1| 0 | Bezeichnung 1
1 | 2| 0 | Bezeichnung 2
2 | 1| 4 | Bezeichnung 3

das Ganze soll so aussehen:
1-1-0 Bezeichnung 1
-2-0 Bezwixhnung 2
2-1-4 Bezeichnung 3

Kann mir mal jemand einen Ansatz geben wie ich das Array automatisch auslesen und die erforderlchen Nodes anlegen kann?
Es muss ja bei jedem Datensatz geschaut werden ob zum Beipiel die Hauptgruppe 1 schon existiert, und dafür dann die Mittelgruppe erstellt werden, hab da irgendwie das Problem das ich das nicht so hinbekomme.
Das array ist so deklariert
ausblenden Delphi-Quelltext
1:
GA_Structure: array of array [0..3of string;					


Mit der Delphi Treeview habe ich bereits mit der Routine die Hauptgruppe anlegen können:
ABer das war nur ein Versuch es geht bestimmt besser:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
if IsDuplicateName(Treeview1.TopItem,HG,true)=false then
  begin
    node:=Treeview1.TopItem;
    TreeView1.Items.AddFirst(Nil,HG);
  end;

function IsDuplicateName(  Node : TTreeNode; sNewName : string; bInclusive : boolean) : boolean;
   var
      TestNode : TTreeNode;
   begin
      if(  Node = nil  ) then
      begin
         Result := false;
         Exit;
      end;

         {Include this Node?}
      if(  bInclusive  ) then
         if(   CompareText(  Node.Text,  sNewName  ) = 0   ) then
         begin
            Result := true;
            Exit;
         end;

         {Test all previous siblings}
      TestNode := Node;
      repeat
            {Get next}
         TestNode := TestNode.GetPrevSibling;

         if(  TestNode <> nil  ) then
               {Is this a duplicate}
            if(   CompareText(  TestNode.Text,  sNewName  ) = 0   ) then
            begin
               Result := true;
               Exit;
            end;
      until (TestNode = nil);


         {Test all next siblings}
      TestNode := Node;
      repeat
            {Get next}
         TestNode := TestNode.GetNextSibling;

         if(  TestNode <> nil  ) then
               {Is this a duplicate}
            if(   CompareText(  TestNode.Text,  sNewName  ) = 0   ) then
            begin
               Result := true;
               Exit;
            end;
      until (TestNode = nil);

      Result := false;
   end;


Naja wie kann ich nun am besten die Unternodes aus dem Array erzeugen?
daywalker0086 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243


Delphi 2005 Architect
BeitragVerfasst: Di 15.03.11 23:09 
Ist warscheinlich zu trivial das jemand antwortet...
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Mi 16.03.11 00:00 
1. Niemals auf bool prüfen siehe hier.
ausblenden Delphi-Quelltext
1:
if IsDuplicateName(Treeview1.TopItem,HG,true)=false then					

2. Vielleicht hilft Dir dieses.
3. Geduld ist eine Tugend, und pushen in kurzer Zeit wird nicht gern gesehen :mahn:

Es wird sicherlich jemand geben der Dir direkt Antworten kann. Auch wenn es mal etwas länger dauert :wink:

Gruss ALf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 16.03.11 06:03 
user profile icondaywalker0086 hat folgendes geschrieben Zum zitierten Posting springen:
Ist warscheinlich zu trivial das jemand antwortet...
Nein, aber du formatierst nicht gerade standardkonform, so dass es ziemlich mühsam ist, deinen Quelltext zu lesen. Deshalb habe ich den Thread gestern direkt wieder zugemacht...

Ja, wie mache ich das in der Regel? Das habe ich schon relativ oft benutzt, egal ob beruflich oder privat, letztlich sieht der Code eigentlich immer ähnlich aus, egal welche Daten hinter der TVirtualStringTree gerade stecken:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
type
  TRegDataTreeNode = record
    NodeData: TSomeData;
    function GetNodeName: string;
  end;
  PRegDataTreeNode = ^TRegDataTreeNode;

function FindChildNode(ParentNode: PVirtualNode; const NodeName: string)
  : PVirtualNode;
var
  TreeNodeData: PRegDataTreeNode;
begin
  Result := FTreeComponent.GetFirstChild(ParentNode);
  while Assigned(Result) do
  begin
    TreeNodeData := PRegDataTreeNode(FTreeComponent.GetNodeData(Result));
    if TreeNodeData.GetNodeName = NodeName then
      Break;
    Result := FTreeComponent.GetNextSibling(Result);
  end;
end;
Mit FindChildNode suche ich nach dem Child mit dem richtigen Namen. Statt GetNodeName kannst du natürlich auch direkt den Namen als Feld in dem Record deklarieren, je nachdem wie deine Datenstruktur im Hintergrund aussieht.

Das rufe ich in einer Schleife auf, in der ich die Bestandteile des Pfads durchgehe. Wenn der Knoten noch nicht existiert, erzeuge und initialisiere ich ihn:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  for i := 0 to High(NodePathList) do
  begin
    Result := FindChildNode(ParentNode, NodePathList[i]);
    if not Assigned(Result) then
    begin
      Result := FTreeComponent.AddChild(ParentNode);
      FTreeComponent.ValidateNode(Result, False);
      InitTreeNode(PRegDataTreeNode(FTreeComponent.GetNodeData(Result)), 
        CurrentPath, NodePathList[i]);
Das ist im Grunde nicht weiter schwer. Der Unterschied zu deinem Code ist hauptsächlich, dass du nicht vom Parent aus das Child suchst, sondern die Nachbarknoten und dass du direkt mit dem Knotentext arbeitest. Einen Knotentext gibt es aber bei der VirtualStringTree nicht, d.h. da musst du über den Datenpointer mit den dahinterliegenden Daten arbeiten.

Je nach Anwendung gibt es bei mir auch noch eine Zwischenschicht zwischen der eigentlichen Datenstruktur und der StringTree, so dass ich verschiedene Datenprovider einklinken kann. Das ist z.B. bei meinem Registryeditor der Fall, da hier verschiedene Datenquellen als Quelle benutzt werden können.