Einzelnen Beitrag anzeigen

jbg

Registriert seit: 12. Jun 2002
3.485 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

Re: VirtualStringTree-Nachladen erst bei Bedarf

  Alt 7. Jun 2008, 08:57
Zitat von DeddyH:
und füge zu jedem Knoten einen "Dummy"-Eintrag hinzu, damit das Plus-Zeichen erscheint.
Wenn man mit OnInitNode und OnInitChildren arbeitet, ist das gar nicht notwendig. Bei OnInitNode stetzt man einfach das "HasChildren" Flag in the "States" und hat das Plus-Symbol. Im OnInitChildren, das einmal für den Parent-Knoten aufgerufen wird, wenn der Benutzer den Knoten öffnet, ermittelt man dann die nächste Ebene und legt die in der eigenen Datenstruktur ab. Für jeden Child-Knoten wird dann wiederum OnInitNode aufgerufen, in dem die eigene Datenstruktur an den Knoten gebunden wird.

Pseudocode:
Delphi-Quellcode:
type
  TDirList = class;
  TDirItem = class;

  TDirItem = class(TObject)
  privtae
    FSubDirs: TDirList;
    FName: string;
    FFullPath: string;
  public
    procedure FillSubDirs;

    property Name: string read FName;
    property FullPath: string read FFullPath;
    property SubDirs: TDirList read FSubDirs;
  end;

  TDirList = class(TObject)
  private
    FItems: TObjectList { of TDirItem }
  public
    procedure Add(AItem: TDirItem);
    procedure Clear;
    property Count: Integer read GetCount;
    property Items[Index: Integer]: TDirItem read GetItem; default;
  end;
 
  PNodeData = ^TNodeData;
  TNodeData = record
    Item: TDirItem;
  end;

  TForm1 = class(TForm)
  ...
  private
    FRoot: TDirItem;
  end;

procedure TForm1.FormCreate(...);
begin
  FRoot := TDirItem.Create('C:', 'C:');
  FRoot.FillSubDirs;

  vstDirs.NodeDataSize := SizeOf(TNodeData);
  vstDirs.RootNodeCount := FRoot.SubDirs.Count;
end;

procedure TForm1.FormDestroy(...);
begin
  //vstDirs.RootNodeCount := 0;
  FRoot.Free;
end;

procedure TForm1.VstInitNode(...);
var
  Data: PNodeData;
  ParentData: PNodeData;
begin
  State := State + [isHasChildren]; // Damit OnInitChildren aufgerufen werden kann und [+] angezeigt wird

  Data := Sender.GetNodeData(Node);
  if GetNodeLevel(Node) = 0 then // erste Ebene
    Data.Item := FRoot.SubDirs[Node.Index] // die im OnCreate oder sonstwo gefüllte DirList nutzen
  else
  begin
    // Die DirList
    ParentData := Sender.GetNodeData(ParentNode);
    Data.Item := ParentData.Item.SubDirs[Node.Index];
  end;
end;

procedure TForm1.VstInitChildren(...);
var
  Data: PNodeData;
begin
  Data := Sender.GetNodeData(Node);
  Data.Item.FillSubDirs();
  ChildCount := Data.SubDirs.Count;
end;

{ TDirItem }

procedure TDirItem.FillSubDirs;
var
  sr: TSearchRec;
begin
  SubDirs.Clear;

  if FindFirst(FullPath + '\*', faDirectory, sr) = 0 then
  try
    repeat
      if (sr.Name <> '.') and (sr.Name <> '..') then
        SubDirs.Add(TDirItem.Create(FullPath + '\' + sr.Name, sr.Name));
    until FindNext(sr) <> 0;
  finally
    FindClose(sr);
  end;
end;
  Mit Zitat antworten Zitat