Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird : TreeView komplett in DB speichern? (https://www.delphipraxis.net/147453-firebird-treeview-komplett-db-speichern.html)

moelski 9. Feb 2010 09:07

Datenbank: Firebird • Version: 2.5 RC • Zugriff über: UniDac

Firebird : TreeView komplett in DB speichern?
 
Moin !

Hat jemand von euch ein Stück Quellcode um einen TreeView in einer FireBird Datenbank zu speichern und wieder zu laden?

Wichtig wären dabei folgende Dinge:
* Die Struktur des Trees (eigentlich logisch :) )
* Die Sortierung
* Letzte Auswahl
* Status für ein- / ausgeklappte Nodes

Die Muhkuh 9. Feb 2010 09:13

Re: Firebird : TreeView komplett in DB speichern?
 
Hi,

fehlt Dir ein Ansatz, wie man es machen könnte oder hast Du einen Ansatz und hoffst, dass jemand sowas in der Art schon erledigt hat?

moelski 9. Feb 2010 09:18

Re: Firebird : TreeView komplett in DB speichern?
 
Moin !

Zitat:

fehlt Dir ein Ansatz
Jain ...
Ich habe eine Lösung für AbsoluteDB. Die kann allerdings nur die reine Struktur speichern. Sortierungen, Selektionen, ... sind da aussen vor.

Zitat:

und hoffst, dass jemand sowas in der Art schon erledigt hat
Das war / ist meine Hoffnung. Denn ich könnte mir vorstellen dass das auch in anderen Anwendungen gebraucht wird. :hi:

RWarnecke 9. Feb 2010 09:20

Re: Firebird : TreeView komplett in DB speichern?
 
Hallo Dominik.

wenn Du hier in der DP suchst nach Hier im Forum suchenTreeView Datenbank findest Du Beispiele oder unter Code-Orakel.

hoika 9. Feb 2010 12:13

Re: Firebird : TreeView komplett in DB speichern?
 
Hallo,

Zitat:

Sortierungen, Selektionen, ... sind da aussen vor.
Hm, Sortierung kann es nur eine geben,
dazu auf oder absteigend.
Das kommt in eigene "Option" Tabelle

Name Char(X)
Value Char(X)

also
"Order", "Name"
"OrderType", "Asc" (oder "Desc")
"Selected", "555" (DB Id des selektierten Knotens)

Ob ein Knoten aus- oder eingeklappt ist,
kommt in die Nodes Tabelle, die ja wohl etwa so aussieht

NodeId DB Id der Nodes
PreNodeId 0 für Root-Node
Expanded Char(1), 1 oder 0


Heiko

moelski 9. Feb 2010 13:14

Re: Firebird : TreeView komplett in DB speichern?
 
Moin !

So ich denke ich habs hinbekommen.
Ist noch auf Basis AbsoluteDB, aber ich denke das Umstellen sollte nicht soo schwer werden.

Laden vom Tree:
Delphi-Quellcode:
procedure TDM.DataBase_OpenFile(Filename : String);
var
  RootNode : TTreeNode;
  RootQuery : TABSQuery;

  procedure AddChildNodes(ParentID: Integer; ParentNode: TTreeNode);
  var
    query : TABSQuery;
    Node : TTreeNode;
  begin
    query := TABSQuery.Create(nil);
    try
      query.DatabaseName := DM.Datasets.DatabaseName;
      query.SessionName := DM.Datasets.SessionName;
      query.SQL.Text := 'SELECT * FROM Datasets WHERE Tree_ParentID='+IntToStr(ParentID)+' ORDER BY Tree_SortOrder';
      query.Open;
      while (not query.EOF) do begin
          Node              := LVMainForm.TV.Items.AddChild(ParentNode, query.FieldByName('Name').AsString);
          Node.Data         := TNodeData.Create;
          Node.ImageIndex   := query.FieldByName('Tree_ImageIndex').AsInteger;
          Node.SelectedIndex := query.FieldByName('Tree_ImageSelect').AsInteger;
          TNodeData(Node.Data).MDI_ID := query.FieldByName('ID').AsInteger;
          // Type als String aus DB lesen und in Auszählungstyp wandeln :-)
          TNodeData(Node.Data).NodeTyp := TLVObjectTyp(GetEnumValue(TypeInfo(TLVObjectTyp),
                                                       query.FieldByName('Typ').AsString));
          TNodeData(Node.Data).MDIFile := query.FieldByName('Filename').AsString;
          AddChildNodes(query.FieldByName('ID').AsInteger, Node);
          if Node.HasChildren then
            Node.Expanded := query.FieldByName('Tree_Expanded').AsBoolean;

          Node.Selected := query.FieldByName('Tree_Selected').AsBoolean;
          query.Next;
        end;
      query.Close;
    finally
      query.Free;
    end;
  end;

begin
  DM.DB.DatabaseFileName := Filename;
  DM.DB.Open;
  DM.Datasets.Open;
  DM.Windows.Open;

  RootQuery := TABSQuery.Create(nil);
  try
    RootQuery.DatabaseName := DM.Datasets.DatabaseName;
    RootQuery.SessionName := DM.Datasets.SessionName;
    RootQuery.SQL.Text := 'SELECT * FROM Datasets WHERE Tree_Depth=0 ORDER BY Tree_SortOrder';
    RootQuery.Open;
    while (not RootQuery.EOF) do begin
        RootNode              := LVMainForm.TV.Items.AddChild(nil, RootQuery.FieldByName('Name').AsString);
        RootNode.Data         := TNodeData.Create;
        RootNode.ImageIndex   := RootQuery.FieldByName('Tree_ImageIndex').AsInteger;
        RootNode.SelectedIndex := RootQuery.FieldByName('Tree_ImageSelect').AsInteger;
        TNodeData(RootNode.Data).MDI_ID := RootQuery.FieldByName('ID').AsInteger;
        // Type als String aus DB lesen und in Auszählungstyp wandeln :-)
        TNodeData(RootNode.Data).NodeTyp := TLVObjectTyp(GetEnumValue(TypeInfo(TLVObjectTyp),
                                                     RootQuery.FieldByName('Typ').AsString));
        TNodeData(RootNode.Data).MDIFile := RootQuery.FieldByName('Filename').AsString;
        AddChildNodes(RootQuery.FieldByName('ID').AsInteger, RootNode);
        if RootNode.HasChildren then
          RootNode.Expanded := RootQuery.FieldByName('Tree_Expanded').AsBoolean;

//        RootNode.Selected := RootQuery.FieldByName('Tree_Selected').AsBoolean;

        RootQuery.Next;
      end;
    RootQuery.Close;
  finally
    RootQuery.Free;
  end;
end;
Reihenfolge neu schreiben:
Delphi-Quellcode:
Procedure TDM.DataBase_WriteSortOrder;
var i, ID : Integer;
    Node : TTreeNode;
begin
  for I := 0 to LVMainForm.TV.Items.Count - 1 do begin
    Node := LVMainForm.TV.Items[I];

    // ID des Node ermitteln
    ID := TNodeData(Node.Data).MDI_ID;
    // ID in DB addressieren
    DM.Datasets.Locate('ID', ID, []);

    // Werte neu eintragen
    with DM.Datasets do begin
      Edit;
      if (Node.Parent <> nil) then
        FieldByName('Tree_ParentID').AsInteger := TNodeData(Node.Parent.Data).MDI_ID
      else
        FieldByName('Tree_ParentID').Clear;

      if Node.HasChildren then
        FieldByName('Tree_Expanded').AsBoolean := Node.Expanded;

      FieldByName('Tree_Selected').AsBoolean := Node.Selected;

      FieldByName('Tree_Depth').AsInteger     := Node.Level;
      FieldByName('Tree_SortOrder').AsInteger := Node.Index;
      Post;
    end;
  end;
end;
Kurze Erklärung zur Tabelle:
Code:
DROP TABLE Datasets;
CREATE TABLE Datasets (
  ID AUTOINC,
  Typ VARCHAR(50),
  Name VARCHAR(50),
  CreateTime DATETIME,
  LastModify DATETIME,
  Filename WIDESTRING(250),
  Tree_ParentID INTEGER,
  Tree_Depth INTEGER,
  Tree_SortOrder INTEGER,
  Tree_Expanded LOGICAL,
  Tree_Selected LOGICAL,
  Tree_ImageIndex SMALLINT,
  Tree_ImageSelect SMALLINT,
  PRIMARY KEY idxPrimaryKey (ID)
);


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:13 Uhr.

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