Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TreeView verknüpfen


Robert - So 18.08.02 22:25
Titel: TreeView verknüpfen
Hi! Dieses Problem wurde schon einmal im alten Delphi-Forum gestellt (nicht von mir), und dort beantwortet. Ich weiß jedoch leider nicht mehr wie es geht.
Ich hätte gerne, wenn man einen Item eines TreeViews anklickt, dass dann in einem Memo-Feld ein zuvor abgespeicherter Text erscheint. Klick man einen anderen Item an, soll der Text, falls er verändert wurde, abgespeichert werden.
Außerdem, und jetzt kommt das eigentlich größte Problem, was mache ich, wenn ich den Namen eines Items ändere. Wie kann die Verknüpfung bestehen bleiben, und wenn ich ihn lösche, wie kann die Datei mit gelöscht werden?

Zur Info: Ich programmiere einen Zeitschriftenverwalter. Ich habe schon mehrere Stunden im Internet nach Freeware gesucht (Google, Metager, Alltheweb). Ich wurde nicht fündig. Noch nicht einmal kostenpflichtige Software, die was taugte!
Es gab einmal eine Shareware, jedoch ist der Server jetzt down. Außerdem konnte man in der Shareware-Version (Vollversion hatte 35DM gekostet) nur 12 Zeitschriften (unbeschränke Artikel- und Programm-auf-CD-Anzahl) abspeichern.

Mit freundlichsten Grüßen in mega-Anzahl
Robert (den-robert@gibts.net)[/u]


Tino - So 18.08.02 22:37

Hallo Robert,

Du kannst jedem Item über das Property Data z. B ein Record zuweisen. Dieses Record könnte dann Deine Informationen enthalten (Dateiname). In der Delphi (6) Hilfe steht ein sehr gutes Beispiel dazu.

Außerdem musst Du eventl. über das Event OnEdited auf das umbennen der Items reagieren. Über das Event OnDeletion erfährst Du wenn ein Item gelöscht wurde.

Hoffe das hat Dir ein wenig geholfen.

Gruß
TINO


Robert - So 18.08.02 23:01
Titel: danke!
Das hat mir geholfen! Ich hab jedoch immer noch eine Frage: Wie findet man heraus, ob ein Item ausgwählt wurde?


MfG
Robert


Arakis - So 18.08.02 23:45

Null Problemo user defined image


Quelltext
1:
2:
if TreeView1.Selected = nil then showmessage('Kein Node ausgewält')
else showmessage('Node wurde ausgewählt');


Bis dann
user defined image


Robert - So 18.08.02 23:47
Titel: ohh
Ohh, da hätt ich wirklich selber drauf kommen können! :oops: :oops: :oops:


Arakis - So 18.08.02 23:50

Macht doch nix, dafür sind wir doch da :wink:

Bis dann
user defined image


GPF - Mo 19.08.02 00:40

Ich empfehle Dir die Nutzung eines anderen Treeviews. Auf http://www.lischke-online.de findest Du das Virtual Treeview. Es ist viel flexibler und deutlich schneller, hat ausserdem weitere Vorzüge wie einfaches Nodemanagement, Spalten im Treeview und eingebautes OLE Drag & Drop - aber auch noch mehr.


Arakis - Mo 19.08.02 00:47

Also ich persönlich finde, dass der VT viel mehr Funktionen hat als der TTreeView. Aber dennoch ist er mir zu kompliziert. Ich hab ihn in mehreren Projekten verwendet, aber ich muss dazu sagen, dass ich hätt alles mit dem TTreeView machen können, wenn sogar noch schneller und einfacher. Z.b ist es doch absurt, dass man eine Caption erst im onGetText zuweisen kann. Aber wenn wir schon mal dabei sind: Wie kann man im TTreeView Nodes per Drag'n'Drop verschieben(und ohne Schutzverletzungen :mrgreen:)

Bis dann
user defined image


Delete - Mo 19.08.02 07:17


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
procedure TForm1.tv1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  ht : THitTests;
  AttachMode : TNodeAttachMode;
begin
  with tv1 do
    begin
      // nur zur Sicherheit
      if(Items.Count = 0) or (Selected = nil) then exit;

      ht  := GetHitTestInfoAt(X,Y);
      ttn := GetNodeAt       (X,Y);

      if(ht - [htOnItem,htNowhere,htOnIndent,htAbove,htBelow] <> ht) then
        begin
          if(htOnItem in ht) then AttachMode := naAddChild
            else if(htNowhere in ht) or (htBelow in ht) then AttachMode := naAdd
              else if(htAbove in ht) then AttachMode := naAddFirst
                else AttachMode := naInsert;

          Selected.MoveTo(ttn,AttachMode);
        end;
    end;
end;

procedure TForm1.tv1DragOver(Sender, Source: TObject;
  X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
  Accept := (Sender is TTreeView);
end;

Dieser Weg prüft aber nicht, ob ein Knoten gleichen Namens evtl. im Ziel schon vorhanden ist. Das dürfte aber nicht das Thema sein, denke ich mal. - Ansonsten: zu unbekannten Funktionen u.ä. bitte die Hilfe referieren. :wink:


Tino - Mo 19.08.02 08:54

GPF hat folgendes geschrieben:
Ich empfehle Dir die Nutzung eines anderen Treeviews. Auf http://www.lischke-online.de findest Du das Virtual Treeview.

Also da kann ich auch nicht so ganz zustimmen. In den meisten Fällen reicht die tTreeView aus. Außerdem finde ich die tTreeView einfacher zu handeln als die Virtual TreeView.

Gruß
TINO


Arakis - Mo 19.08.02 09:12

@MathiasSimmack: Du hast in der Deklaration "ttn: TTreeNode;" vergessen :wink:
Das Meiste ist klar, nur was ist THitTests für ein Ding user defined image

Bis dann
user defined image


Robert - Mo 19.08.02 12:56
Titel: nee
Hi! Danke für den Tipp mit dem VT, aber ich glaube ich benutze weiterhin den TTreeview, da ich mich sonst erst wieder umgewöhnen müsste, und hier auch die überwiegende Zahl von User geschrieben hat, dass es schwerer zu bedienen ist.
Trotzdem danke.


Delete - Mo 19.08.02 13:38

Arakis hat folgendes geschrieben:
@MathiasSimmack: Du hast in der Deklaration "ttn: TTreeNode;" vergessen :wink:

Sorry, mein Fehler.

Zitat:
Das Meiste ist klar, nur was ist THitTests für ein Ding

F1!


Arakis - Mo 19.08.02 13:52

MathiasSimmack hat folgendes geschrieben:
F1!


Jaja, hab ich schon längst gemacht. Nur sitzte ich hier gerade vor einem PC mit Delphi 6 PE, da ist die Hilfe mager und in Englisch. Wollte es mir ja nur "bequem" machen :mrgreen:
Gut, ich werde auch selber herausfinden, was THitTests für ein Ding ist :twisted:

Bis dann
user defined image


Robert - Mo 19.08.02 22:28
Titel: Pointer?
Hi! Ich hab ein Problem: Was ist Pointer für eine Variable?
Wie bringe ich bei TreeView1.Selected.Data
einen String rein?
Bitte antwortet schnell! So lange kann ich überhaupt nicht weiterprogrammieren. In der Delphi (5) Hilfe habe ich bereits gesucht.


Arakis - Mo 19.08.02 22:46

Nana, mal nicht drängeln :wink:

Dazu musst du eine Klasse, Objekt oder Recordset deklarieren, dessen Zeiger du in data speicherst.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    private
      { Private-Deklarationen }
    public
      { Public-Deklarationen }
  end;

type
  TMeineTreeDaten = Class
    Public
      MeinString: String;
    End;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  //Klasse deklarieren
  MeineTreeDaten: TMeineTreeDaten;
begin
  //Klasse erstellen
  MeineTreeDaten := TMeineTreeDaten.Create;
  //Klasse mit Daten füttern
  MeineTreeDaten.MeinString := 'Irgendwas';
  //Zeiger abspeichern
  TreeView1.Selected.Data := MeineTreeDaten;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  //Klasse deklarieren
  MeineTreeDaten: TMeineTreeDaten;
begin
  //Weise der Klasse den Zeiger zu
  MeineTreeDaten := TMeineTreeDaten(TreeView1.Selected.Data);
  //werte die Daten aus
  showmessage(MeineTreeDaten.MeinString);

  //Wenn du den Eintrag nicht mehr brauchst, dann gib wieder den Speicher frei:
  MeineTreeDaten.Destroy;
end;

end.


Bis dann
user defined image


Robert - Di 20.08.02 00:20
Titel: Super!
Hi! Ich werde den Code morgen (oder wohl eher später) testen. Aber vielen vielen Dank!

Zitat:
Nana, mal nicht drängeln :wink:

Wieso drängeln? Ich habe dieses Thema doch eröffnet. Oder
versteh ich da was falsch?


Arakis - Di 20.08.02 00:23

Zitat:
Bitte antwortet schnell! So lange kann ich überhaupt nicht weiterprogrammieren

So was könnte man als drängeln bezeichnen. :wink:

Bis dann
user defined image


Robert - Di 20.08.02 09:08
Titel: ok
Okay, okay! Ab sofort werde ich schreiben:

Bitte beantwortet zuerst alle anderen Fragen von AUQ.de! Dann beantwortet bitte meine Frage. Ich kann schließlich nur nicht weiterprogrammieren. :wink:


Besser so?


Robert - Di 20.08.02 10:23
Titel: Speichern und Laden
Hi! Ich habe noch mal 'ne Frage dazu:
Wenn ich mitTreeview1.SaveToFile('Daten.dat');speichere, dann sind die Daten nach dem Laden beim Programmstart, die ich inTreeview1.Selected.Dataabgespeichert hatte, gelöscht. Und es gibt eine Zugriffsverletzung.
Wie kann ich diese Daten abspeichern?


Arakis - Di 20.08.02 10:31

Hier sind wir an einem Punkt, wo es kompliziert wird. Dies zu realisieren würde den Rahmen dieses Thema sprengen. Aber zur Info: Wenn du den Baum speicherst, werden ja auch nur die Zeiger mitgespeichert. Da beim Neuladen die Zeiger auf ein digitales Nirva zeigen, kommt es zu Zugriffsverletzungen. Um einen den Baum zu speichern, müsstest du eine eigene Speicherroutine schreiben, die alle Nodes und die Daten mit speichert. Das macht man am besten mit einem Stream.

Bis dann
user defined image


Robert - Di 20.08.02 10:45
Titel: ohh :!:
Und man könnte also sagen, dass ich das Programm vergessen kann, oder wie? Davon habe ich nämlich nicht die geringste Ahnung.
Gibts denn keine einfache Möglichkeit bei einem TreeView-Node einen Pfad zu speichern? :roll:


Arakis - Di 20.08.02 10:47

Wenn du nicht die geringste Ahnung hast, dann würde ich mit einem etwas kleinerem Projekt anfangen. Aber trotzdem tolle Mutivation user defined image

Bis dann
user defined image


Robert - Di 20.08.02 11:15
Titel: Idee!
Hi! Warum kompliziert, wenns auch leicht geht?:

Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.TreeView1GetSelectedIndex(Sender: TObject;
  Node: TTreeNode);
begin
Memo1.Lines.SaveToFile(ExtractFilePath (Application.EXEName) + '\daten\artikel\' + markiert + '.dat');
Markiert := TreeView1.Selected.Text;
Memo1.Lines.LoadFromFile(ExtractFilePath (Application.EXEName) + '\daten\artikel\' + markiert + '.dat');
end;

Es funktioniert super! :D


Robert - So 25.08.02 23:47

Hi! Wenn man die Icons abspeichern will, ist das exakt das gleiche Problem, oder?