Hallo Real_Thunder,
vor dem Problem stand ich vor ein paar Tagen auch,
ich habe es so gelöst (mit dem
VirtualStringTree von Mike Lischke):
Delphi-Quellcode:
Type
TBaseTreeObj = class
Caption: String;
ID: integer;
ParentID: integer;
OrderSeq: integer;
Level: integer;
end;
PTreeData = ^TTreeData;
TTreeData = record
TreeObj: TBaseTreeObj;
end;
[...]
function TVirtualStringTreeHandle.AddNodeByParentID(aParentID: integer; aTreeObj: TBaseTreeObj): PVirtualNode;
function FindParentNode(ParentID: Integer): PVirtualNode;
var
NodeData: PTreeData;
begin
Result:= fVST.GetFirst;
while Assigned(Result) do
begin
NodeData:= PTreeData(fVST.GetNodeData(Result));
If NodeData^.TreeObj.ID = ParentID then
exit;
Result:= fVST.GetNext(Result);
end;
end;
var
Data: PTreeData;
LNode: PVirtualNode;
begin
If not assigned(aTreeObj) then exit;
If aParentID = 0 then
result:= fVST.AddChild(nil) else
result:= fVST.AddChild(FindParentNode(aParentID));
fVST.ValidateNode(Result, False);
Data:= fVST.GetNodeData(Result);
{ TreeObjekt-Pointer zuweisen }
Data^.TreeObj:= aTreeObj;
end;
function TVirtualStringTreeHandle.BuildTreeFromDataSource(aQuery: TQuery): Boolean;
var
BaseTreeObj: TBaseTreeObj;
ParentID: integer;
begin
fVST.BeginUpdate;
fVST.Clear;
try
with aQuery do
begin
while not EOF do
begin
{ Event abfeuern, um Daten zu holen und TreeObjekt zu erstellen }
FillTreeObjWithTableData(aQuery, BaseTreeObj);
// HIER KANNST DU STATT EINES EVENTS DIREKT DIE DATEN AUS
// DEM AKTUELLEN DATENSATZ DEM KNOTEN ANHÄNGEN
{ Knoten hinzufügen, indem nach Elter-ID gesucht wir }
AddNodeByParentID(BaseTreeObj.ParentID, BaseTreeObj);
next;
end;
end;
finally
fVST.EndUpdate;
end;
aQuery.First;
If fVST.GetFirst <> NIL then
begin
FocusedNode(fVST.GetFirst);
fVST.Expanded[fVST.GetFirst]:= true;
end;
end;
Erklärung:
Die Datenbank hat wie schon im Beitrag darüber erwähnt, u.a.
die Felder ID und ParentID. Jeder Eintrag weiß also, wem er
gehört.
Du sortierst zuvor die
DB nach ID und übergibst die
Query
der Funktion "BuildTreeFromDataSource".
Wenn du allerdings Drag & Drop planst, dann ist die Sortierung
nach ID nicht unbedingt mehr gültig; unter Umständen hättest du
dann zuerst den "ChildNode" vor dem "ParentNode".
Aus diesem Grund habe ich noch die Felder "Level" und "OrderSeq"
eingeführt und lasse die Tabelle nach diesen Feldern aufsteigend
sortieren. Nach jedem Drag & Drop müssen diese natürlich
aktualisiert werden.
Der Tree hat bei mir ein Objekt anstatt nur eines Records, damit
ich das Objekt später für andere Verwendung erweitern kann.
Du kannst es natürlich nur über ein Record lösen.
Edit: Du musst dem VirtualStringTree sagen, welche Größe du
an Daten im Knoten übergibst. Zudem gibt es eine fast unüber-
schaubare Anzahl an Einstellmöglichkeiten.
Zur Einführung fand ich dieses Tutorial ganz gut.
Gruß
Pfoto