TTreeView und ich werden keine Freunde

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
stinketier
Beiträge: 40
Registriert: Di 3. Mär 2015, 15:35

TTreeView und ich werden keine Freunde

Beitrag von stinketier »

Hallo Zusammen,

Seit Jahren drücke ich mich vor dem Thema TreeView. Nun aber als guten Vorsatz für den Sommer.

Also ziel ist es eine Art Ordnerstruktur abzubilden. Nun Frage ich mich wie Speichere ich denn das in die Datenbank?
Die ID's ändern sich ja ständig(also immer wenn ein Eintrag/Untereintrag dazu kommt)

Und wie erkenne ich überhaupt ob das ein "Untereintrag" ist und was die Eltern sind?

Also Blöd gefragt wie bekomme ich das in eine Datenbank?

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    TreeView1: TTreeView;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure TreeView1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;


implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
   if (TreeView1.Items.SelectionCount  = Null ) then begin
      TreeView1.Items.add(Nil,Edit1.text)
   end else begin
      TreeView1.Items.AddChild(Treeview1.Selected, Edit1.text);
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   TreeView1.Items.add(Nil,'Ordner 1');
   TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Unter Ordner 1');
   TreeView1.Items.AddChild(TreeView1.Items.Item[0], 'Unter Ordner 2');
   TreeView1.Items.AddChild(TreeView1.Items.Item[0], 'Unter Ordner 3');
   TreeView1.Items.AddChild(TreeView1.Items.Item[1], 'Unter Unter Ordner 1');
   TreeView1.Items.AddChild(TreeView1.Items.Item[1], 'Unter Unter Ordner 2');
   TreeView1.Items.add(Nil,'Ordner 2');
   TreeView1.Items.add(Nil,'Ordner 3');

end;

procedure TForm1.TreeView1Click(Sender: TObject);
begin
  // gibt den Makierten Text wieder
//   ShowMessage(Treeview1.Selected.text);
// Zählt die Einträge von oben nach unten druch das ist nicht möglich das in die Datenbank zuschreiben
//   ShowMessage(Inttostr(Treeview1.Selected.AbsoluteIndex));
end;

end.
blöd zuerklären irgendwie

stinketier
Beiträge: 40
Registriert: Di 3. Mär 2015, 15:35

Re: TTreeView und ich werden keine Freunde

Beitrag von stinketier »

achso
das Wiki hilft mir nicht weiter

https://wiki.freepascal.org/TTreeView

da schaue ich immer zuerst nach

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: TTreeView und ich werden keine Freunde

Beitrag von fliegermichl »

Jede Node hat eine Eigenschaft Parent in der ein Zeiger auf die übergeordnete Node ist.
Bei der allerersten Node ist diese Eigenschaft = nil.

Dann hat jede Node eine Eigenschaft Index die angibt, die wievielte Node sie im Parent ist.
Mit diesen Information kann man rekursiv durch den Tree iterieren und die Nodes in der Datenbank abspeichern.

Das mit der Rekursion ist einem Anfänger etwas schwierig zu erklären aber ich versuch's mal.

Nimm mal als Beispiel eine Festplatte. Wenn du mit dem Explorer in das Hauptverzeichnis schaust, dann siehst du da Ordner und Dateien.
Gehst du nun in einen der Ordner rein, dann finden sich da wieder Ordner und Dateien.
Das Spiel geht immer so weiter bis man irgendwann einen Ordner hat, in dem es keine weiteren Unterordner gibt.

Eine rekursive Funktion bearbeitet immer nur einen Ordner. Für eventuell vorhandene Unterordner ruft sie sich selbst mit dem Unterordner als Parameter auf.
Dieses sich selbst aufrufen muß aber zwingend irgendwann beendet werden (Man nennt das "die Rekursion muss terminieren")

Genauso kann man sich durch einen Treeview hangeln und eine nach der anderen Node in der Datenbank abspeichern.

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: TTreeView und ich werden keine Freunde

Beitrag von six1 »

^Hi,
es gibt eine DBTreeView Komponente.
Schau mal hier:
https://forum.lazarus.freepascal.org/in ... msg=302754
Gruß, Michael

stinketier
Beiträge: 40
Registriert: Di 3. Mär 2015, 15:35

Re: TTreeView und ich werden keine Freunde

Beitrag von stinketier »

six1 hat geschrieben:
Fr 23. Apr 2021, 12:10
^Hi,
es gibt eine DBTreeView Komponente.
Schau mal hier:
https://forum.lazarus.freepascal.org/in ... msg=302754
joar würde ich gerne nutzen
nur irgendwie komme ich mit der Demo im Link überhaupt nicht weiter :(

Das ist einfach ärgerlich das es in dem Lazarus ordner keine Demos mehr drin sind :(

stinketier
Beiträge: 40
Registriert: Di 3. Mär 2015, 15:35

Re: TTreeView und ich werden keine Freunde

Beitrag von stinketier »

egal was ich versuche das funktioniert nicht

das kann ja nicht sein das es keiner benutzt
also grade probiere ich die TJvDBTreeView aus

das gleiche wie immer

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  JvDBTreeView1.Items.add(Nil,'Ordner 1');
  JvDBTreeView1.DataSource.DataSet.Insert;
  JvDBTreeView1.DataSource.DataSet.POST;

end;      
und wie immer kommt nix (Leere Felder) an in der Datenbank

das kann doch nicht sein

Achso Anzeigen aus der Datenbank geht nur das hinzufügen funktioniert überhaupt nicht

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: TTreeView und ich werden keine Freunde

Beitrag von wp_xyz »

stinketier hat geschrieben:
Di 27. Apr 2021, 17:13
das kann ja nicht sein das es keiner benutzt
also grade probiere ich die TJvDBTreeView aus
Zumindest ich, denn ich habe die Delphi-Version nach Lazarus übertragen. Hast du dir das Beispiel-Programm angesehen? (Im Ordner Examples der jvcllaz-Installation)
stinketier hat geschrieben:
Di 27. Apr 2021, 17:13

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  JvDBTreeView1.Items.add(Nil,'Ordner 1');
  JvDBTreeView1.DataSource.DataSet.Insert;
  JvDBTreeView1.DataSource.DataSet.POST;
end;      
Zwischen Insert und Post musst du natürlich die Felder mit den neuen Werten bestücken.

Beim JvDBTreeView brauchst du zuminedst diese Felder:
* Masterfield - der Name des übergeordneten Feldes
* Detailfield - der Name des untergeordneten Feldes
* ItemField - die Bezeichnung des Feldes.
Angenommen, dein Dataset enthält die Bundesländer und Landkreise von Deutschland. Dann ist der oberste Node "Deutschland" mit Masterfield -1 (kein Master, weil es der oberste Knoten ist) und als DetailField 0 und als "ItemField" den Text "Deutschland". Das Bundesland Bayern hat dann als Detailfield z.B. 1 und als Masterfield den Wert 0 - weil es zu Deutschland gehört, und als ItemField den Text "Bayern". Hessen hätte Detailfield 2 und als Masterfield wieder 0, usw. Bei den Landkreisen hätte Frankfurt das Detailfeld z.B. 3 und als Masterfield den Detailfield-Wert von Hessen, also 2. usw.

stinketier
Beiträge: 40
Registriert: Di 3. Mär 2015, 15:35

Re: TTreeView und ich werden keine Freunde

Beitrag von stinketier »

????

momentmal die neuen felder sind doch schon in der DataSource drin?

Code: Alles auswählen

  JvDBTreeView1.Items.add(Nil,'Ordner 1');
Oder muss ich das per Hand hinzufügen?



Ja die Demo hab ich mir schon angesehen
Sie zeigt aber nur das Anzeigen und nicht das hinzufügen

und ja die Struktur hab ich genauso


* Masterfield - Integer
* Detailfield - Integer
* ItemField - Varchar(40)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: TTreeView und ich werden keine Freunde

Beitrag von wp_xyz »

Es ist vom Grundgedanken wie beim DBGrid: Die Daten kommen aus dem Dataset, DBGrid bzw.JvDBTreeView zeigen sie lediglich an. Manipulationen, die du am DBGrid bzw. JvDBTreeView vornimmst, kommen nicht unbedingt im Dataset an und bleiben nicht notwendigerweise erhalten.

Um einen Node einzufügen, musst du ihn im Dataset einfügen, nicht im Tree. Also:

Code: Alles auswählen

  Dataset.Insert;
  Dataset.FieldByName(...).AsInteger := ...
  // auch alle anderen Felder des neuen Records befüllen
  Dataset.Post; 
Nach dem Post wird der Tree neu eingelesen, und du bekommst auf diese Weise den neuen Node zu Gesicht. Genauso aber auch im DBGrid, wenn beide vom selben Dataset versorgt werden.

Schau dir mal beigefügtes Beispiel an. Es ist das Beispiel aus JVCL, das um Routinen zum Einfügen, Löschen und Bearbeiten erweitert wurde. Außerdem wurde ein Event-Handler für TJvDBTreeView.OnEdited geschrieben, der den geänderten Node.Text in die DB schreibt.
Dateianhänge
jvdbtreeview_insert.zip
(10.14 KiB) 75-mal heruntergeladen

stinketier
Beiträge: 40
Registriert: Di 3. Mär 2015, 15:35

Re: TTreeView und ich werden keine Freunde

Beitrag von stinketier »

sehr cool das hilft mir schonmal weiter

hach aber es scheint das TreeView und SQLite keine freunde sind.
seit heute hab ich dieses Problem hier:
Tree.PNG
Tree.PNG (4.92 KiB) 2096 mal betrachtet
die Tabelle wurde aber so angelegt:

Code: Alles auswählen

CREATE TABLE [Tree] (
[MasterFieldID] INTEGER,
[DetailFieldID] INTEGER,
[ItemText] VARCHAR(40)
);
Also das Feld ist ein Integer
ich bekomme die Meldung immer wenn ich es Auswählen will:
Einstellung.PNG
Einstellung.PNG (39.03 KiB) 2096 mal betrachtet
was kann denn das schonwieder sein?

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: TTreeView und ich werden keine Freunde

Beitrag von wp_xyz »

Keine Ahnung, ich glaube aber nicht, dass das etwas mit dem DBTreeView zu tun hat. Ich habe eben das Demo-Programm von BufDataset auf SQLite3 umgestellt, und das funktioniert genauso wie die alte Version.

Antworten