Einzelnen Beitrag anzeigen

Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Treeview mit daten füllen

  Alt 27. Dez 2007, 17:56
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
Jürgen Höfs
  Mit Zitat antworten Zitat