AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein VirtualTreeView mit DIContainers kombinieren
Thema durchsuchen
Ansicht
Themen-Optionen

VirtualTreeView mit DIContainers kombinieren

Ein Thema von Wishmaster · begonnen am 17. Jun 2020 · letzter Beitrag vom 22. Jun 2020
Antwort Antwort
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#1

VirtualTreeView mit DIContainers kombinieren

  Alt 17. Jun 2020, 03:55
so ich versuche seit geraumer zeit die VirtualTreeView mit DIContainers zu kombinieren
ich habe zwei VirtualTreeView's die ich miteinander verlinken will. jede VirtualTreeView hat mehrere kolumnen
im endeffekt soll das genauso aussehen und funktionieren wie die "RegEdit" in windows.

ich will die die daten manuell eintragen, editieren, löschen und natürlich Speichern und Laden können.

ich habe eine funktionierende demeo gebastelt allerdings benutze ich da die Absolute Database


mit der Compo. DIContainers ich weiß nicht einmal wo ich anfangen soll. wäre jemand bereit mir ne kleine Demo zu schreiben?

siehe anhang wie das ganze aussehen soll
Miniaturansicht angehängter Grafiken
pasman.jpg  
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 17. Jun 2020, 09:32
Ich kenne diese Komponentensammlung konkret nicht, aber beim lesen der Website erscheint es mir auch nur eine aufgebohrte Version von Listen- und anderen Datenklassen zu sein.
Im Prinzip verheiratest du den VirtualTreeView damit genauso bzw. so ähnlich, als wenn du eine normale Delphi TList/TList<T> o.ä. hättest.
Es finden sich im Forum zahlreiche Beispiele dafür, insbesondere die Beiträge von User Aviator sind immer sehr hilfreich.

Welche konkrete Datenklasse nutzt du denn aus den DIContainers (TDITree, TDIList, TDIHash...)?
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 17. Jun 2020, 09:58
Und für das Zeugs will der tatsächlich 118.99 Euro?
Benutz Spring4D - das ist Open Source Eventuell noch den TreeviewPresenter aus DSharp und du hast das Ding schon fast fertig.

P.S. Echt unglücklich vom Author, das DIContainers zu nennen, als ich das Thema las, dachte ich wirklich an was anders
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
freimatz
Online

Registriert seit: 20. Mai 2010
1.443 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 17. Jun 2020, 12:14
Ich auch. Habe kurz reinschaut. "Last modified: 2016". Ich sehe keine Vorteile das zu verwenden.
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#5

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 19. Jun 2020, 05:13
danke für die schnelle antwort.


@Stevie ich kannte die zwei komponenten nicht, ich habe sie installiert und nur kurz angeschaut, sehen vielversprechend aus.
ich muss nur rauskriegen wie ich nodes and subnodes kreieren kan. einige der demos funktionieren nicht mehr.


in der VirtualTreeviewSample demo habe ich den folgenden code gefunden, das erklärt aber nicht wie ich ne node und subnode (Node:= VSTree.AddChild) in der VirtualTreeview kreiere kan.
und natürlich wie ich das ganze Speicher/Lade
ich muss mich etwas mehr damit befassen. ich bin aber für jede hilfe/Demo dankbar.




Delphi-Quellcode:
procedure TMainForm.AddContactClick(Sender: TObject);
var
  LContact: TContact;
begin
  LContact := TContact.Create('FirstName', 'LastName');
  ContactsPresenter.View.ItemsSource.Add(LContact);
  ContactsPresenter.View.CurrentItem := LContact;
end;



procedure TMainForm.FormCreate(Sender: TObject);
var
  list: IList<TObject>;
begin
  list := TObservableCollection<TObject>.Create();
  list.Add(TContact.Create('John', 'Doe'));
  list.Add(TContact.Create('Jane', 'Doe'));
  list.Add(TContact.Create('Baby', 'Doe'));
  ContactsPresenter.View.ItemsSource := list as IObjectList;



  
  ....


ich habe versucht mit dem hersteller von der DIContainers Compo. zu arbeiten. aber bei der ersten frage wurde der so aggressive, da denkt man zweimal nach beforman im ne frage stellt.

Geändert von Wishmaster (19. Jun 2020 um 06:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 19. Jun 2020, 10:03
Du erzeugst keine Nodes selber, du hängst eine IObjectList und ein oder mehrere DataTemplates an den TVP. Die DataTemplates bestimmen, welche Daten angezeigt werden und ob und welche Elemente in der Ebene darunter angezeigt werden.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
344 Beiträge
 
Delphi 2007 Professional
 
#7

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 19. Jun 2020, 10:05
ein Beipiel mit mehreren Ebenen gibt es hier.

jus
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 19. Jun 2020, 11:17
Also im ersten Moment dachte ich bei DI auch an etwas anderes.

Ich habe jetzt einfach mal ein Beispiel gemacht, wie man einen VST auch mit einer TObjectList<T> befüllen kann. Vielleicht reicht dir das ja auch schon. Für totale VST Neulinge habe ich den Code auch etwas dokumentiert. Allerdings in Englisch, damit auch Nicht-Deutsche damit etwas anfangen können.

Vielleicht hilft es dir ja weiter.
Angehängte Dateien
Dateityp: zip VSTSample.zip (7,6 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#9

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 21. Jun 2020, 22:25
noch einmal danke für die demo es ist aber leider nicht was ich wollte.
kann sein dass ich mich falsch ausgedrückt hatte aber mir ging es darum [2] VirtualTreeViews miteinander zu verbinden
ohne dabei auf eine DB zu setzen wie (Absolute Database), ich wollte meinen eigenen password manage schreibe wie das programm (KeePass)
woh jeder record/node eine dynamische größe hat und bem speichern nur die felder speichert die tatsächlich einen eintrag enthalten um so die Datei so klein wie möglich zu halten.
deswegen hatte ich ursprünglich die Compo DIContainers gewählt weil da ne demo drin ist "DIContainers_AddressBook" die sah vielversprechend aus.
doch leider kam ich da nicht weiter sie umzuschreiben damit ich [2] VirtualTreeViews benutzen kann mit unendlich vieleen einträge auf beider seiten.

ihr könnt euch das so vorstellen wie der file explore in windows. du klickst auf einen ordner auf der linken seite und auf der rechten seite werden die datein die in dem ordner drin sind angezeiget,
oder RegEdit


so wenn ihr euch das bild im ersten pos anschaut, weiß ich wie man die virtualTreeView mit Daten füllt, das ist nicht das problem.



@Aviator
die Demo ist überkompliziert und dasselbe kannst auch einfacher/schnell/kleiner machen mit nem normalen record. es sei denn ich übersehe etwas/ en forteil.



das ist die datenstrukture die ich vorher benutzt hatte mit der Absolute Database.

Delphi-Quellcode:
(**************************** Create Encrypted File ***************************)

function TMain_Form.Create_EncryptedFile(const Filename : String; DeletePass : Boolean) : Boolean;
//var GraphicCompressionAlgorithm: TCompressionAlgorithm;
begin
  Result:= False;
  DBFilename:= FileName;


 with SecureDB do
  begin
   if Exists then
    Close;
  end;

 with Folder_Table do
  begin
   if Exists then
    Close;
  end;

 with Record_Table do
  begin
   if Exists then
    Close;
  end;


 if not ShowPassDialog('Create a new Password database') then
  begin
   SecureDB.Password:= '';
   exit;
  end;


 if (Length(SecureDB.Password) = 0) then
  Exit;

 with SecureDB do
  begin
    DatabaseName:= 'SecureDB';
    DatabaseFileName:= DBFilename;
    PageSize:= 2048;
    PageCountInExtent:= 8;
    MaxConnections:= 1;
    MultiUser:= false;
    Exclusive:= true;
   if Exists then
    begin
     Close;
     DeleteDatabase;
    end;
  end;


 (* Folder Table *)

 with Folder_Table do
  begin
    DatabaseName:= 'SecureDB';
    TableName:= 'FolderList';
   with AdvFieldDefs do
    begin
     Clear;
     Add('ID', aftAutoIncLargeint, 0, false);
     Add('ParentID', aftLargeint);
     Add('IconId', aftLargeint);
     Add('Icon', aftGraphic, 0, false, caZLIB, 4);
     Add('Title', aftWidestring, 255);
    end;
   with IndexDefs do
    begin
     Clear;
     Add('ID', 'ID', [ixPrimary]);
     Add('ByParentID', 'ParentID', []);
     Add('ByTitle', 'Title', []);
    end
  end;

 (* Record Table *)

 with Record_Table do
  begin
    DatabaseName:= 'SecureDB';
    TableName:= 'RecordList';
   with AdvFieldDefs do
    begin
     Clear;
     Add('ID', aftAutoIncLargeint, 0, false);
     Add('ParentID', aftLargeint);
     Add('FolderID', aftLargeint);
     Add('Icon', aftGraphic, 0, false, caZLIB, 4);
     Add('Title', aftWidestring, 255);
     Add('Value', aftWideMemo, 0, False, caZLIB, 4);
     Add('Comment', aftWideMemo, 0, False, caZLIB, 4);
     Add('File', aftBlob, 0, False, caZLIB, 4);
     Add('FileName', aftWideMemo, 0, False, caZLIB, 4);
     Add('IsHidden', aftBoolean);
     Add('Colored', aftBoolean);
     Add('ItemColor', aftWidestring, 10);
     Add('FontColor', aftWidestring, 10);
     Add('FontBold', aftBoolean);
    end;
   with IndexDefs do
    begin
     Clear;
     Add('ID', 'ID', [ixPrimary]);
     Add('ByParentID', 'ParentID', [ixDescending]); // RecordTree Folder
     Add('ByFolderID', 'FolderID', []); // FolderTree Folder
     Add('ByTitle', 'Title', []);
    end;
  end;




  {
  FieldByName('ItemColor').AsWideString := ColorToHex(Data.ItemColor);
  FieldByName('FontColor').AsWideString := ColorToHex(Data.FontColor);
  FieldByName('FontBold').AsBoolean    := Data.FontBold;


  }



 try
 (* create the database *)
  with SecureDB do
   begin
    if not Exists then
     CreateDatabase;
   end;

  (* create the Folder Table table *)
  with Folder_Table do
   begin
    if not Exists then
     CreateTable;
   end;

  (* create the Record Table table *)
  with Record_Table do
   begin
    if not Exists then
     CreateTable;
   end;

  if DeletePass then
   SecureDB.Password:= '';
   Result:= True;

 except
  on E: Exception do

 end;
end;
Delphi-Quellcode:
(******************************* Fill Folder-List *****************************)

function TMain_Form.FolderList_Fill(ExpandedNood : Boolean) : boolean;
 procedure FillTreeNode(Parent: PVirtualNode);
 var Node: PVirtualNode;
     Data: PNodeData;

     // test
     BlobImage : TStream;
     Image : TBitmap;
 begin
  if Assigned(Parent) then
   begin

     Data:= FolderTree.GetNodeData(Parent);
     Folder_Table.Filter:= 'ParentID = ' + IntToStr(Data^.ID);
     Folder_Table.Filtered:= true;
     Folder_Table.First;

    while not Folder_Table.Eof do
     begin
      Node:= FolderTree.AddChild(Parent);
      Data:= FolderTree.GetNodeData(Node);
      Data^.ID:= Folder_Table.FieldByName('ID').AsLargeInt;
      Data^.Title:= Folder_Table.FieldByName('Title').AsWideString;
      Data^.IconID:= Folder_Table.FieldByName('IconID').AsLargeInt;
      Folder_Table.Next;
     end;


     Node:= Parent.FirstChild;
    while Assigned(Node) do
     begin
      FillTreeNode(Node);
      FolderTree.Expanded[Node]:= true;
      Node:= Node.NextSibling;
     end;

   end;
 end;

 var Node, RootNode: PVirtualNode;
     Data: PNodeData;
begin
  Result:= False;
  FolderTree.BeginUpdate;
 try
  FolderTree.Clear;



  Node:= FolderTree.AddChild(Nil);
  Data:= FolderTree.GetNodeData(Node);
  Data^.ID:= 0;
  Data^.Title:= 'My Passwords';
  Data^.Value:= '';
  Data^.IconID:= 0;
  FillTreeNode(Node);

 (* Expand first nood 'My Passwords' *)
  RootNode:= FolderTree.GetFirst();
  FolderTree.Expanded[RootNode]:= ExpandedNood;
 finally
  FolderTree.EndUpdate;
  RecordTree_Fill(0, False);
  Result:= True;
 end;
end;
Delphi-Quellcode:
(******************************* Fill Record-List *****************************)


function TMain_Form.RecordTree_Fill(FolderID: Integer; ExpandedNood : Boolean): boolean;
var
 I : Integer;
 urlStartPos, urlStrLength: Integer;

procedure FillTreeNode(Parent : PVirtualNode);
var
 Node : PVirtualNode;
 Data : PNodeData;
 RecordData: TRecordData;
begin

 if Assigned(Parent) then
  begin
    Data:= RecordTree.GetNodeData(Parent);
    Record_Table.Filter:= 'ParentID = ' + IntToStr(Data^.ID)
    + ' ' + 'AND' + ' ' + 'FolderID = ' + IntToStr(FolderID);

    Record_Table.Filtered:= true;
    Record_Table.First;

   while not Record_Table.Eof do
    begin
     Node:= RecordTree.AddChild(Parent);
     Data:= RecordTree.GetNodeData(Node);

     Data^.ID:= Record_Table.FieldByName('ID').AsLargeInt;
     Get_Record_Data(RecordData, true);
     Data^.Title:= RecordData.Title;
    if RecordData.IsHidden then
     Data^.Value:= '[xxxxxxxx]'
    else
     Data^.Value:= RecordData.Value;

    if not RecordData.IsHidden then
     Data^.IsLink:= IsURL(RecordData.Value)
    else
     Data^.IsLink:= False;

     Data^.ItemColored:= RecordData.ItemColored;
     Data^.ItemColor:= RecordData.ItemColor;
     Data^.FontColor:= RecordData.FontColor;
     Data^.FontBold:= RecordData.FontBold;
     Data^.IconId:= I;

     RecordListImg.Add(TImageHolder.Create);
     RecordListImg.Items[I].Image:= RecordData.Icon;

     Inc(I);
     Clear_Record_Data(RecordData);
     Record_Table.Next;
    end;

    Node:= Parent.FirstChild;
   while Assigned(Node) do
    begin
      FillTreeNode(Node);
      Node:= Node.NextSibling;
    end;

  end;
end;

var
 Node, RootNode: PVirtualNode;
 Data : PNodeData;
 Image : TBitmap;
 j : Integer;
begin
  Result:= False;
  RecordTree.BeginUpdate;

  RecordTree.Clear;

 for J:= RecordListImg.Count -1 downto 0 do
  RecordListImg.Delete(j);

 if RecordListImg.Count > 0 then
  RecordListImg.DeleteRange(0, RecordListImg.Count - 1);

 try
  Image := TBitmap.Create;
  Image.PixelFormat := pf32bit;
  Image.Width:= Record_ImList16.Width;
  Image.Height:= Record_ImList16.Height;
  Record_ImList16.GetBitmap(0, Image);

  RecordListImg.Add(TImageHolder.Create);
  RecordListImg.Items[0].Image:= Image;
  Image.Free;


  Node:= RecordTree.AddChild(Nil);
  Data:= RecordTree.GetNodeData(Node);
  Data^.ID:= 0;
  Data^.Title:= 'Root';
  Data^.IconId:= 0;
  I:= 1;

  FillTreeNode(Node);


 (* Expand first nood 'My Passwords' *)
  RootNode:= RecordTree.GetFirst();
  RecordTree.Expanded[RootNode]:= True;// ExpandedNood;
 finally
  RecordTree.EndUpdate;

  Result:= True;
 end;
end;

Geändert von Wishmaster (22. Jun 2020 um 04:47 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: VirtualTreeView mit DIContainers kombinieren

  Alt 22. Jun 2020, 21:12
ich wollte meinen eigenen password manage schreibe wie das programm (KeePass)
woh jeder record/node eine dynamische größe hat und bem speichern nur die felder speichert die tatsächlich einen eintrag enthalten um so die Datei so klein wie möglich zu halten.
Hier würde ich eher darauf setzen, einen entsprechend guten Serializer zu verwenden oder zu programmieren. JSON wäre hier sogar eine Option bei der alle Werte die nil sind nicht serialisiert werden. Somit hast du die geringst mögliche Textbasierte Form deiner Klasse. Du kannst dir natürlich auch einen eigenen Dateitypen generieren.
Aber all das hat nichts damit zu tun, wie du die Daten im Programm vorhälst. Und erst recht nicht damit, wie du die Daten nachher anzeigen möchtest.

@Aviator
die Demo ist überkompliziert und dasselbe kannst auch einfacher/schnell/kleiner machen mit nem normalen record. es sei denn ich übersehe etwas/ en forteil.
Der Grund ist ganz einfach der, dass die Daten nicht vom VST sondern von einer, nicht von der Oberfläche abhängigen, ObjectList vorgehalten werden. An diese ObjectList kannst du alles anbinden was du willst. Prinzipiell das, was du auch mit dieser Komponentensammlung erreichen willst (so vermute ich).

Wenn du auf Records aufbaust, dann müsstest du das pro VST immer wieder machen. Und wenn du Records in einer Art Liste oder einem Array speichern willst, dann kannst du auch gleich eine Klasse verwenden und die Vorteile derer nutzen.

Mach es so wie du es für richtig hälst. Ich habe nur eine Demo mit, in meinen Augen, Best Practices vorbereitet. Zumindest hat es sich über viele Jahre dazu entwickelt und sich bisher immer wieder bewährt.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:38 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