Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi VirtualTreeView und Baumstruktur (https://www.delphipraxis.net/18656-virtualtreeview-und-baumstruktur.html)

Albi 22. Mär 2004 20:17


VirtualTreeView und Baumstruktur
 
Schönen guten Abend,

ich habe mir die Kompo von Delphi Gems geholt und stehe nun vor dem Problem, das ich keien SubNode hingefügt bekomme.

Das heißt, ich weiß wie das per Btn anstelle aber ich hole mir die Daten aus einer Query und trage die in einen Record. Nun stehen in der Abfrage aber noch weitere Daten diese möchte ich in die SubNode eintragen. So das es dann in etwa so aussieht.

|-Name
|--Name1
|--Name2

Über diesen Code trage schreibe ich die Daten in die ListView.

Delphi-Quellcode:
 CustRec:= Sender.GetNodeData(Node);
  Initialize(CustRec^);
  CustRec.AVorname:= Query1.Fields[0].AsString;
  CustRec.AName:= Query1.Fields[1].AsString;
  CustRec.AVornameGF1:= Query1.Fields[2].AsString;
  CUstRec.ANameGF1:= Query1.Fields[3].AsString;
  if not Query1.Eof Then
    Query1.Next;
end;

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var CustRec: PCustRec;
begin
  CustRec:= Sender.GetNodeData(Node);
  If Column = 0 Then
    CellText:= CustRec.AVorname;
  IF Column = 1 Then
    CellText:= CustRec.AName;
end;

Albi 24. Mär 2004 11:29

Re: VirtualTreeView und Baumstruktur
 
Weiß keiner von Euch einen Rat? Oder irgendeine andere Kompo die mir das möglich macht?

DelphiDeveloper 24. Mär 2004 13:04

Re: VirtualTreeView und Baumstruktur
 
habe hier mal ein paar code schnipsel zusammengeschrieben wie ich das geamcht habe.

1.) Definition der Daten die ich brauche

Delphi-Quellcode:
 TTreeDataClass = class
  private
    FTestStr1: string;
    FDokID: integer;
    FKDID: integer;
    FICON: integer;
    FDOKNR: string;
    FMASUCH: string;
    FDokDatum: TDate;
    FUserInitial: string;
    FMandant: integer;
    FDokArt: TDokTypen;
    FDokKuerzel: string;
  published
    property TestStr1: string read FTestStr1 write FTestStr1;
    property DokID: integer read FDokID write FDokID;
    property KDID: integer read FKDID write FKDID;
    property ICON: integer read FICON write FICON;
    property DokDatum: TDate read FDokDatum write FDokDatum;
    property UserInitial: string read FUserInitial write FUserInitial;
    property Mandant: integer read FMandant write FMandant;
    property DOKNR: string read FDOKNR write FDOKNR;
    property MASUCH: string read FMASUCH write FMASUCH;
    property DokArt: TDokTypen read FDokArt write FDokArt;
    property DokKuerzel: string read FDokKuerzel write FDokKuerzel;
  end; //class

  PTreeData = ^TTreeData;
  TTreeData = record
    FObject: TObject;
  end;
2. Methode fuer das Hinzufuegen von Nodes
Delphi-Quellcode:
function TFormChildArchiv.AddVSTObject(avst: TCustomVirtualStringTree;
  aNode: PVirtualNode; aObject: TObject): PVirtualNode;
var
  Data: PTreeData;
begin
  Result := avst.AddChild(aNode);
  avst.ValidateNode(Result, False);
  data := avst.GetNodeData(Result);
  data^.FObject := aObject;
end;
3. Füllen der Datenstrukturen mit werten aus der DB

Delphi-Quellcode:
procedure TFormChildArchiv.BuildTree;
var
  TreeObject: TTreeDataClass;
  Wurzel: PVirtualNode;
begin

  vst.BeginUpdate;

  vst.NodeDataSize := SizeOf(TTreeData);
  vst.DeleteChildren(vst.RootNode, true);

  if markiert(ANGEBOT) then
  begin
   
    // Root eintragen
    TreeObject := TTreeDataClass.Create;
    try
      TreeObject.DokArt := ANGEBOT;
      TreeObject.DokKuerzel := 'ANG';
      TreeObject.TestStr1 := GetDKBEZ(GetEnumName(TypeInfo(TDokTypen),
        ord(TreeObject.Dokart))) +
        '(' + IntTostr(IB_QryAngebote.RecordCount) + ')';

      if IB_QryAngebote.RecordCount > 0 then
        TreeObject.Icon := 3
      else
        TreeObject.Icon := 12;

      Wurzel := addvstObject(vst, nil, TreeObject);
      // jetzt Detail eintragen
      with IB_QryAngebote do
      begin
        while not Eof do
        begin
          TreeObject := TTreeDataClass.Create;
          try
            TreeObject.TestStr1 := FieldByName('KU_SUCH').AsString;
            TreeObject.DokID := FieldByName('AK_ID').AsInteger;
            TreeObject.KDID := FieldByName('AK_KU_ID').AsInteger;
            TreeObject.DokDatum := FieldByName('AK_DATUM').asdate;
            TreeObject.UserInitial := FieldByName('USER_INITIAL').asString;
            TreeObject.Mandant := FieldByName('AK_MANDANT').AsInteger;
            TreeObject.DOKNR := FieldByName('AK_NR').asstring;
            // TreeObject.Icon := 17;
            addvstObject(vst, Wurzel, TreeObject)  
         except
            TreeObject.free
          end; //try
          Next;
        end; //while
      end;
    except
      TreeObject.free
    end; //try
    IB_QryAngebote.Close;
  end; // if Angebote eintragen


  if markiert(ANFRAGE) then
  begin
   
    // Root eintragen
    TreeObject := TtreeDataClass.Create;
    try
      TreeObject.dokart := ANFRAGE;
      TreeObject.DokKuerzel := 'ANF';
      TreeObject.TestStr1 :=
        GetDKBEZ(GetEnumName(TypeInfo(TDokTypen),
        ord(TreeObject.Dokart))) +
        '(' + IntTostr(IB_QryAnfragen.RecordCount) + ')';
      if IB_QryAnfragen.RecordCount > 0 then
        TreeObject.Icon := 3
      else
        TreeObject.Icon := 12;
      Wurzel := addvstObject(vst, nil, TreeObject);
      // jetzt Detail eintragen
      with IB_QryAnfragen do
      begin
        while not Eof do
        begin
          TreeObject := TTreeDataClass.Create;
          try
            TreeObject.TestStr1 := FieldByName('KU_SUCH').AsString;
            TreeObject.DokID := FieldByName('AN_ID').AsInteger;
            TreeObject.KDID := FieldByName('KU_ID').AsInteger;
            TreeObject.DokDatum := FieldByName('AN_SERVERDATUM').asdate;
            TreeObject.UserInitial := FieldByName('USER_INITIAL').asString;
            TreeObject.Mandant := FieldByName('MANDANT_ID').AsInteger;
            TreeObject.DOKNR := FieldByName('AN_NR').asstring;
            // TreeObject.Icon := 17;
            addvstObject(vst, Wurzel, TreeObject);    
          except
            TreeObject.free;
          end; //try
          Next;
        end; // while
      end; // with
    except
      TreeObject.Free
    end; //try
    IB_QryAnfragen.Close;
  end; // if
unter 3 steht noch viel balast das entscheidende fuer die Baumstruktur
ist addvstObject

Albi 24. Mär 2004 19:38

Re: VirtualTreeView und Baumstruktur
 
Vielen Dank für den Code,ich habe ihn auch schon ausprobiert aber nun stehe vor dem nächsten Problem. Was muß noch machen, das er mir die Daten im VST anzeigt. So wie ich das bisher probiert habe geht das ja nicht mehr.

Bisher habe ich das mit CellText:= .... gemacht aber hier funzt das nicht.

Langsam glaube ich nicht mehr daran das diese Kompo so einfach ist wie ich das gelesen habe.

DelphiDeveloper 24. Mär 2004 20:34

Re: VirtualTreeView und Baumstruktur
 
folgende Events sind fuer den anfang interessant
der code gehoert zum sourcecode von oben ich hoffe du kommst damit klar:


1. Anzeigen Text
Delphi-Quellcode:
procedure TFormChildArchiv.vstGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: Integer; TextType: TVSTTextType;
  var CellText: WideString);
var
  Data: PTreeData;

begin
  Data := Sender.GetNodeData(Node);
  if data.FObject <> nil then
  begin
    case Column of
      0:
        begin
          if Node.Parent = Sender.RootNode then

            celltext := TTreeDataClass(Data.FObject).FTestStr1
          else
            celltext := TTreeDataClass(Data.FObject).FTestStr1
        end;
      1:
        if Node.Parent = Sender.RootNode then
          celltext := ''
        else
          celltext := DateTostr(TTreeDataClass(Data.FObject).FDokDatum);
      2:
        if Node.Parent = Sender.RootNode then
          celltext := ''
        else
          celltext := TTreeDataClass(Data.FObject).MASUCH;
      3:
        if Node.Parent = Sender.RootNode then
          celltext := ''
        else
          celltext := TTreeDataClass(Data.FObject).FUserInitial;
      4:
        if Node.Parent = Sender.RootNode then
          celltext := ''
        else
          celltext := TTreeDataClass(Data.FObject).FDOKNR;

    end;
  end;
end;
2. bildchen anzeigen
Delphi-Quellcode:
procedure TFormChildArchiv.vstGetImageIndex(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Kind: TVTImageKind; Column: Integer;
  var Ghosted: Boolean; var ImageIndex: Integer);
var
  Data: PTreeData;

begin
  Data := Sender.GetNodeData(Node);

  case Kind of
    ikNormal, ikSelected:
      if (Column = 0) and (Node.Parent = Sender.RootNode) then
        ImageIndex := TTreeDataClass(Data.FObject).Icon;
    ikState:
      case Column of
        0:
          if Node.Parent <> Sender.RootNode then
            ImageIndex := 5;
      end;
  end;
end;
3. sortieren der spalten
Delphi-Quellcode:
procedure TFormChildArchiv.vstHeaderClick(Sender: TVTHeader;
  Column: Integer; Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  if Button = mbLeft then
  begin
    with Sender, Treeview do
    begin
      if SortColumn > NoColumn then
        Columns[SortColumn].Options := Columns[SortColumn].Options + [coParentColor];

      // Do not sort the last column, it contains nothing to sort.
      if Column = 0 then
        SortColumn := NoColumn
      else
      begin
        if (SortColumn = NoColumn) or (SortColumn <> Column) then
        begin
          SortColumn := Column;
          SortDirection := sdAscending;
        end
        else
          if SortDirection = sdAscending then
            SortDirection := sdDescending
          else
            SortDirection := sdAscending;

        Columns[SortColumn].Color := $F7F7F7;
        SortTree(SortColumn, SortDirection, False);
      end;
    end;
  end;
end;

procedure TFormChildArchiv.vstCompareNodes(Sender: TBaseVirtualTree; Node1,
  Node2: PVirtualNode; Column: Integer; var Result: Integer);
var
  Data1, Data2: PTreeData;
begin
  Data1 := Sender.GetNodeData(Node1);
  Data2 := Sender.GetNodeData(Node2);

  case Column of
    0:
      Result := CompareText(TtreeDataClass(Data1.FObject).TestStr1,
        TtreeDataClass(Data2.FObject).TestStr1);
    1:
      Result := Trunc(TTreeDataClass(Data1.FObject).DokDatum -
        TTreeDataClass(Data2.FObject).DokDatum);
    2:
      Result := CompareText(TTreeDataClass(Data1.FObject).MASUCH,
        TTreeDataClass(Data2.FObject).MASUCH);
    3:
      Result := CompareText(TTreeDataClass(Data1.FObject).UserInitial,
        TTreeDataClass(Data2.FObject).UserInitial);
    4:
      Result := StrToInt(TTreeDataClass(Data1.FObject).DOKNR) -
        StrToInt(TTreeDataClass(Data2.FObject).DOKNR);
  end;
end;
4. Freigeben der Nodes

Delphi-Quellcode:
procedure TFormChildArchiv.vstFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  Data: PTreeData;
begin
  Data := VST.GetNodeData(Node);
  if not Assigned(Data) then
    exit;
  Data.FObject.Free;
end;
Hoffe du kommst damit zurecht

Albi 25. Mär 2004 06:23

Re: VirtualTreeView und Baumstruktur
 
Vielen Dank für die Hilfe, ich habe deinen Code etwas abgeändert und habe nun nach einer Woche mühne und viel Hilfe von Dir das gewünschte Ergebnis.

Hier nun der Code für alle die das gleiche Problem haben.

Delphi-Quellcode:
Procedure TForm1.BuildTree;
var
  TreeObject: TTreeDataClass;
  Wurzel: PVirtualNode;
begin
  VST.BeginUpdate;
  VST.NodeDataSize:= SizeOf(TTreeData);
  VST.DeleteChildren(VST.RootNode, true);
  While Not Query1.Eof Do
  Begin
  TreeObject:= TTreeDataClass.Create;                  
  TreeObject.Vorname:= Query1.FieldByName('MVorname').AsString; //Hier werden die Root eingetragen
  TreeObject.Name:= Query1.fieldByName('MName').AsString;
  Wurzel:= AddVSTObject(VST, Nil, TreeObject);
  If Query1.FieldByName('MNameGF1').AsString > '' Then //hier werden die Notes eingelesen
    Begin
      TreeObject:= TTreeDataClass.Create;
      Try
        If Query1.FieldByName('MNameGF1').AsString > '' Then
        Begin
        TreeObject.NameGF1:= Query1.FieldByName('MNameGF1').AsString;
        TreeObject.VornameGF1:= Query1.FieldByName('MVornameGF1').AsString;
        AddVstObject(VST,wurzel, TreeObject);
        end;
      except
      TreeObject.Free;
      end;
    end;
    Query1.Next;
   end;
   VST.EndUpdate;
end;
Den Rest habe ich wie oben gelassen und ich kann nur noch vielen Dank sagen.

Albi 25. Mär 2004 10:19

Re: VirtualTreeView und Baumstruktur
 
So jetzt habe ich alles hinbekommen und es läuft ohne Probleme. Eine frage habe ich da jetzt jedoch noch. Was muß ich einstellen, das ich auch nach der ersten Spalte sortieren kann. Ich habe jetzt schon die Bsp durchgeschaut und die Einstellungen vergleichen aber nichts gefunden. Ich habe mit Sicherheit nur was übersehen aber ich find es einfach nicht.

DelphiDeveloper 25. Mär 2004 10:57

Re: VirtualTreeView und Baumstruktur
 
Delphi-Quellcode:

procedure TFormChildArchiv.vstHeaderClick(Sender: TVTHeader;
  Column: Integer; Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  if Button = mbLeft then
  begin
    with Sender, Treeview do
    begin
      if SortColumn > NoColumn then
        Columns[SortColumn].Options := Columns[SortColumn].Options + [coParentColor];


        if (SortColumn = NoColumn) or (SortColumn <> Column) then
        begin
          SortColumn := Column;
          SortDirection := sdAscending;
        end
        else
          if SortDirection = sdAscending then
            SortDirection := sdDescending
          else
            SortDirection := sdAscending;

        Columns[SortColumn].Color := $F7F7F7;
        SortTree(SortColumn, SortDirection, False);



    end;
  end;
end;
geht es nicht wenn du meine Sonderbehandlung der 0.ten spalte rausscheißt.
Habs mal bei mir auf die schnelle gemacht und es funzt.

Albi 25. Mär 2004 12:16

Re: VirtualTreeView und Baumstruktur
 
Hab ich dann auch gesehen. War bis dahin aber der Meinung das es an der VST Einstellung liegt. Bis ich mir den Quelltext der Beispiele angesehen habe und da kam dann die Erleuchtung.

So jetzt hab ich alles und es sieht viel schöner und sortierter aus als nur in ner ListView.

DelphiDeveloper 25. Mär 2004 12:58

Re: VirtualTreeView und Baumstruktur
 
Ja der Virtual TreeView ist eine Leistungsstarke Komponente. Auf den ersten
Blick ein wenig schwierig zu handeln aber wenn man es dann mal verstanden hat,
kommt man schon klar.

Mike Lischke sei dank!
Virtual Tree View


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz