![]() |
Re: Virtual Treeview - Nodes durch-iterieren - Wie?
Zitat:
Das was Du auf dem Bild sehen kannst, sind einfach Panels. Bei der Umsetzung der anderen Struktur, wie sie gern in Organigrammen benutzt wird, hakt es allerdings noch gewaltig. Das Problem ist eben einfach, dass jedes Kind, welches wieder eigene Kinder hat seinen eigenen visuellen Bereich markieren muss. Ich versuch das mal in einem kommenden Bild klarzumachen. Zitat:
Hier mal der aktuelle Code zum Generieren. Ich habe den Code aus der hier angebotenen Routine ForceTreeToList umgebaut. Nicht schön, aber es funktioniert. Sicher ist das schon etwas zu viel. Wenn erwünscht, stelle ich auch gern mal die aktuelle EXE ein, damit man sich selbst ein Bild machen kann. Ich werde jetzt noch ein Bild erzeugen und später anhängen, welche die Probleme besser verständlich visualiseren soll. Vielen Dank schon vorab.
Delphi-Quellcode:
//diese procedure wird jedes mal ausgelöst, wenn man was am treeview macht...
procedure TForm1.CreateDiagram; var //myButton : TButton; myButton : TAdvSmoothButton; i, k, int_obj_width, int_Top_offset, main_Left, int_Left_offset : integer; int_level_count, int_items_on_level : integer; myFirstNode, myHelpNode : PVirtualNode; akt_Node, last_Node: PVirtualNode; Data: PTreeData; begin //löschen aller elemente auf der scrollbox while ScrollBox1.ControlCount > 0 do ScrollBox1.Controls[0].Free; //wenn struktur vertikal dann das hier //funzt schon sehr gut... case rad_type_struc.ItemIndex of 0,1 : begin int_top := 0; int_left := 20; obj_counter := 0; Memo1.Clear; ForceTreeToList(nil, Memo1.Lines,-1); exit; end; end; //ansonsten struktur = horizontal [b]//ab hier haperts gewaltig[/b] int_obj_width := 100; int_Top_offset := 20; int_Left_offset := 40; int_level_count := 0; main_Left := 0; //sammeln der levels //diese routine zählt die max. leveltiefe in einem virtuellen treeview myFirstNode := form2.vst.GetFirst; myHelpNode := form2.vst.GetFirst; while not(form2.vst.GetLast(nil) = myHelpNode) do begin if form2.vst.GetNodeLevel(myHelpNode) > int_level_count then //counter hochzählen int_level_count := form2.vst.GetNodeLevel(myHelpNode); //helpnode auf nächste node verweisen myHelpNode := form2.vst.GetNext(myHelpNode); end; with form2.vst do begin akt_Node := GetFirst; last_Node := GetLast(nil); while not(akt_Node = last_Node) do begin myButton := TAdvSmoothButton.Create(self); myButton.Parent := ScrollBox1; myButton.Top := (akt_node.Index * 65) + int_Top_offset; myButton.Height := 30; inc(main_Left); myButton.Width := int_obj_width; int_items_on_level := GetItemsOfLevel(form2.vst.GetNodeLevel(akt_Node)); myButton.Left := ((ScrollBox1.Width div int_items_on_level) * (main_Left div 10)) - (myButton.Width div 2) ; Data := GetNodeData(akt_Node); myButton.Caption := Data.FCaption; myButton.Visible := true; myButton.Appearance.Font.Color := FontDialog1.Font.Color; myButton.Appearance.Font.Size := FontDialog1.Font.Size; myButton.Appearance.Font.Style := FontDialog1.Font.Style; myButton.BevelColor := ColorBD.Color; myButton.Color := ColorBG.Color; akt_Node := GetNext(akt_Node); end; end; end; //diese procedure ruft die erzeuger-routine CreateLable auf und übergibt ihr wichtige daten procedure TForm1.ForceTreeToList(Tree:TTreeView; Lines:TStrings; Layers:Integer=-1); const // Verschiedene Zeichen für die Darstellung definieren intLeft1 : integer = 60; intLeft2 : integer = 0; intLeft3 : integer = 40; intLeft4 : integer = 40; procedure ForceChilds(fNode:PVirtualNode; strSpace:String; fLayer:Integer); var fChild:PVirtualNode; Data: PTreeData; begin // Für jeden Knoten und dessen Unterknoten wird ein Eintrag in // die Liste geschrieben. Um dies rekursiv zu machen, ruft sich die // Funktion selber wieder auf wenn ein weiterer Knoten mit Unterknoten // gefunden wurde. Aber immer nur solange bis die Anzahl Layers erreicht // wurde. if (assigned(fNode)) and ((fLayer < Layers) or (Layers = -1)) then begin Inc(fLayer); if (Form2.vst.HasChildren[fnode]) then begin inc(obj_counter); Data:=form2.VST.GetNodeData(fNode); int_top := obj_counter * 40; case rad_type_struc.ItemIndex of 0 : int_left:= (form2.vst.GetNodeLevel(fNode)+1) * 40; 1 : int_left:= ScrollBox1.Width - ((form2.vst.GetNodeLevel(fNode)+1) * 40) - 100; end; CreateLabel(int_top, int_left,Data.FHeight, Data.FWidth, form2.vst.GetNodeLevel(fNode), Data.FCaption); case rad_type_struc.ItemIndex of 0 : int_left:= int_left + intLeft3; 1 : int_left:= ScrollBox1.Width - (int_left + intLeft3) - 100; end; fChild:=form2.vst.GetFirstChild(fnode); repeat ForceChilds(fChild,strSpace,fLayer); fchild:=form2.vst.GetNextSibling(fchild); until not assigned(fChild); case rad_type_struc.ItemIndex of 0 : int_left := intLeft1; 1 : int_left := ScrollBox1.Width - intLeft1 - 100; end; end else begin inc(obj_counter); Data:=form2.VST.GetNodeData(fNode); int_top := obj_counter * 40; case rad_type_struc.ItemIndex of 0 : int_left := (form2.vst.GetNodeLevel(fNode) + 1) * intLeft3; 1 : int_left := ScrollBox1.Width - ((form2.vst.GetNodeLevel(fNode) + 1) * intLeft3) - 100; end; CreateLabel(int_top, int_left,Data.FHeight, Data.FWidth, form2.vst.GetNodeLevel(fNode), Data.FCaption); end; end; end; var Node: PVirtualNode; begin with form2.vst do begin BeginUpdate; Node := GetFirst; while Assigned(node) do begin ForceChilds(Node,'',0); Node := form2.vst.GetNextSibling(node); end; EndUpdate; end; end; //die bezeichnung ist nicht ganz korrekt, da kein label erstellt wird, sondern panels oder buttons //die procedure selbst ruft abhängig vom gewählten style eine weitere unterprozedur auf zum erstellen des panels //und erzeugt selbst dann noch ein paar shapes als verbinder zwischen den panels procedure TForm1.CreateLabel(objTop, objLeft, objHeight, objWidth, objLevel : integer; objText:String); var myShape : TShape; begin //objText := objText + inttostr(obj_counter); case rad_type_button.ItemIndex of 0 : CreateButtonWin(objTop, objLeft, objHeight, objWidth, objLevel,objText); 1 : CreateButtonXP(objTop, objLeft, objHeight, objWidth, objLevel,objText); 2 : CreateButtonGlas(objTop, objLeft, objHeight, objWidth, objLevel,objText); 3 : CreateButtonGlow(objTop, objLeft, objHeight, objWidth, objLevel,objText); end; //erstelle lines zwischen controls if obj_counter > 1 then begin //horizontales shape myShape := TShape.Create(form1); myShape.Parent := ScrollBox1; myShape.Height := 1; myShape.Width := 20; case rad_type_struc.ItemIndex of 0 : myShape.Left := objLeft - 20; 1 : myShape.Left := objLeft + 100; end; myShape.Top := objTop + 12; //vertikales shape myShape := TShape.Create(form1); myShape.Parent := ScrollBox1; myShape.Width := 1; case rad_type_struc.ItemIndex of 0 : myShape.Left := objLeft - 20; 1 : myShape.Left := objLeft + 120; end; if objLevel = 1 then begin myShape.Height := ((obj_counter-1) * 40) - 17; myShape.Top := 70; end else begin myShape.Height := 22; myShape.Top := objTop - 10 end; end; end; //diese procedure erzeugt ein panel zur visualisierung eines treeview-items procedure TForm1.CreateButtonWin(objTop, objLeft, objHeight, objWidth, objLevel : integer; objText:String); var myButton : TPanel; begin myButton := TPanel.Create(self); myButton.Parent := ScrollBox1; myButton.Top := objTop; myButton.Left := objLeft; myButton.Caption:= objText; myButton.Width := 100; myButton.Height := 30; myButton.Visible:= true; myButton.Font.Color := FontDialog1.Font.Color; myButton.Font.Size := FontDialog1.Font.Size; myButton.Font.Style := FontDialog1.Font.Style; myButton.Font.Name := FontDialog1.Font.Name; //myButton.BevelColor := ColorBD.Color; myButton.Color := ColorBG.Color; end; |
Re: Virtual Treeview - Nodes durch-iterieren - Wie?
Hallo
< Das Problem ist eben einfach, dass jedes Kind, welches wieder eigene Kinder hat seinen eigenen > < visuellen Bereich markieren muss. Ich versuch das mal in einem kommenden Bild klarzumachen. > wenn du das als Panel machst, sollte das doch gehen. Unter-Diagramme landen als eigenständiges Panel auf dem Panel des Eltern-Diagramms (Parent entsprechend setzen). Die Panels kannst du übrigens durch folgenden Code direkt mit der Maus verschieben (klappt bei meinem Form zumindestens).
Delphi-Quellcode:
procedure TPanel1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); begin ReleaseCapture; Perform(WM_SYSCOMMAND, SC_MOVE + 1, 2); end; Heiko |
Re: Virtual Treeview - Nodes durch-iterieren - Wie?
Liste der Anhänge anzeigen (Anzahl: 1)
Und zum besseren Verständnis hier das versprochene Bild mit einigen Kommentaren. Rechts im Bild seht Ihr den dazugehörenden Treeview. Ich will eigentlich "nur". das Generieren der Panels wie im vorangegangenen Thread automatisiert erledigen.
Da ich die Struktur des Treeviews nicht kennen kann, muss das Ganze logisch erfolgen und jedes Parent, welches Childs hat, müsste checken, wieviele Childs es hat und dann entsprechend der Anzahl genügend Raum für diese reservieren. Da kann man sicher auch hier und da was mit Offsets machen, aber wenn der Baum gewaltig in die Tiefe geht, könnts auch haarig werden. Ich habe noch keinen gangbaren Weg gefunden. Kann mir von Euch jemand auf die Sprünge helfen - Bitte? |
Re: Virtual Treeview - Nodes durch-iterieren - Wie?
Zitat:
Das Verschieben der Panel ist schon drin, und soll eigentlich nur im Notfall zum Einsatz kommen. Aktuell habe ich leider noch keinen richtig funktionierenden Weg gefunden überhaupt die Positionen automatisiert hinzubekommen...für die horizontale Lösung... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz