Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
Delphi XE5 Professional
|
Re: Virtual Treeview - Nodes durch-iterieren - Wie?
11. Mär 2009, 10:20
Zitat von hoika:
Hallo,
unwahrscheinlich, dass der VST das kann.
Zeig doch mal, wie es bisher aussieht ?
Oder ist das das 2. Bild ?
Heiko
Also das Bild baum.png ist das, was ich bisher schon realisiert habe. Das Ganze habe ich optional schon links- und rechtsbündig...
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 von generic:
Eigentlich gilt hier im Forum: Neue Frage = neuer Post!
Bild 1 ist nicht möglich, würde ich selbst malen.
Bild 2 ist möglich über die Paint Ereignisse.
Ja, ich verspreche hiermit hoch und heilig, dass ich mich das nächste mal dran halte. Ich hatte die Organigramm vor 2 Wochen in einem anderen Forum gestellt und 0 Antworten erhalten. Jetzt habe ich hier mal Feedback. Das will ich mir mit nem neuen Post nicht kaput machen, denn ich brauche Hilfe, da ich bei LOGISCHEN Dingen nicht so der Burner bin.
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;
Danke
Tom
|