Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TreeView: Ordner und Dateien


Coder - Fr 15.10.04 18:13
Titel: TreeView: Ordner und Dateien
Hi
Ich hab ein TreeView und zwei Buttons. Mit den Buttons soll man Ordner und Dateien in das TreeView einfügen können.

Delphi-Quelltext
1:
  TreeView1.Items.AddChild(TreeView1.Selected,'Neuer Ordner');                    

Das funktioniert schonmal.
Aber wie macht man es, das in eine Datei keine weitere Datei einzufügen geht und sie so zum Ordner wird?


Moderiert von user profile iconChristian S.: Topic aus CLX / Delphi Language (Object-Pascal) verschoben am Fr 15.10.2004 um 22:45


Coder - Fr 15.10.04 21:45

Ich glaube ich bekomme es jetzt doch alleine hin. :D


Christian S. - Fr 15.10.04 21:46

Dann poste bitte auch die Lösung, damit auch anderen geholfen wird.


Das gehört auch zum guten Ton ;-)


Coder - Fr 15.10.04 21:52

Ich glaube das wäre nicht angebracht da es waaahhnsinnig bescheuert ist.
Immer wenn ich eine Datei/Item erstelle wird in ein Memo das Item eingetragen. Jedesmal wenn ich einen Ordner oder eine Item erstelle wir geprüft ob das selektierte Item darin ist, wenn ja, wird der Ordner oder das Item nicht erstellt.
Das Memo benuzte ich gleichzeitig noch um Text darin abzuspeichern der in ein RichEdit geschrieben wird, sobald das passende Item ausgewählt ist.


Christian S. - Fr 15.10.04 21:58

Hallo!

Ich würde das über den Data-Pointer machen, den jeder TreeNode besitzt. Die einfachste Möglichkeit wäre wohl, dort keinen Zeiger auf irgendwelche Daten zu speichern, sondern einfach einen Integer.

Also so irgendwie (aus dem Kopf, daher ohne Gewähr):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
const folderNode = 1;
const fileNode = 2;
{...}
var myNode : TTreeNode;
{...}
myNode := TreeView1.Items.AddChild(TreeView1.Selected,'Neuer Ordner');
myNode.Data := Pointer(folderNode);


und auslesen kannst Du das dann:

Delphi-Quelltext
1:
if Integer(myNode.Data) = fileNode then istKeinOrdner;                    


MfG
Christian


Coder - Fr 15.10.04 22:14

Wie? So?

Delphi-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:
{...}

const
  folderNode = 1;
  fileNode = 2;

var
  {...}
  myNode : TTreeNode;

{...}

procedure TForm1.NodeButton1Click(Sender: TObject);
begin
  if Integer(myNode.Data) = fileNode then
  begin
    TreeView1.Items.AddChild(TreeView1.Selected,'Neue Notiz');
    myNode.Data := Pointer(fileNode);
  end;
end;

procedure TForm1.FolderButton1Click(Sender: TObject);
begin
  if Integer(myNode.Data) = fileNode then
  begin
    myNode :=  TreeView1.Items.AddChild(TreeView1.Selected,'Neuer Ordner');
    myNode.Data := Pointer(folderNode);
  end;
end;

Ich blick jetzt garnichts mehr. :eyecrazy:


Christian S. - Fr 15.10.04 22:26

Nee, nicht ganz! :D

Das "myNode" beim Auslesen ist nicht das "myNode" beim Eintrag. Ich hätte das wohl unterscheiden sollen. Es sollte so aussehen:


Delphi-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:
{...}

const
  folderNode = 1;
  fileNode = 2;

var
  {...}
  myNode : TTreeNode;

{...}

procedure TForm1.NodeButton1Click(Sender: TObject);
begin
  if Integer(TreeView1.Selected.Data) <> fileNode then //Der ausgewählte Node darf kein fileNode sein
  begin
    TreeView1.Items.AddChild(TreeView1.Selected,'Neue Notiz'); //füge Node hinzu
    myNode.Data := Pointer(fileNode); //markiere Node als fileNode
  end;
end;

procedure TForm1.FolderButton1Click(Sender: TObject);
begin
  if Integer(TreeView1.Selected.Data) <> fileNode then //Der ausgewählte Node darf kein fileNode sein
  begin
    myNode :=  TreeView1.Items.AddChild(TreeView1.Selected,'Neuer Ordner'); //füge Node hinzu
    myNode.Data := Pointer(folderNode); //markiere Node als folderNode
  end;
end;


Ich würde sagen, so geht es. *hoff*


Coder - Fr 15.10.04 22:42

Er compiliert zwar, aber sobald ich einen Button drücke gibt es eine Zugriffsverletzung. Ich glaube sie ist in der ersten if Zeile. Liegt es vieleicht daran das noch kein item im TreeView ist?


((Ich muss jetzt erstma ins Bett und das Wochenende über bin ich in Dresden. :( ))


Christian S. - Fr 15.10.04 22:45

Coder hat folgendes geschrieben:
Er compiliert zwar, aber sobald ich einen Button drücke gibt es eine Zugriffsverletzung. Ich glaube sie ist in der ersten if Zeile. Liegt es vieleicht daran das noch kein item im TreeView ist?
Ja. Ich war davon ausgegangen, dass das vorher überprüft wird. Er kann natürlich kein Data von etwas abrufen, was es nicht gibt.


Coder - So 17.10.04 19:22

THX! Nach einer kleinen veränderung geht es!

Delphi-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:
procedure TForm1.NodeButton1Click(Sender: TObject);
begin
  if TreeView1.Items.Count<>0 then
  begin
    if Integer(TreeView1.Selected.Data) <> fileNode then //Der ausgewählte Node darf kein fileNode sein
    begin
      myNode := TreeView1.Items.AddChild(TreeView1.Selected,'Neue Notiz'); //füge Node hinzu
      myNode.Data := Pointer(fileNode); //markiere Node als fileNode
    end;
  end
  else
  begin
    myNode := TreeView1.Items.AddChild(TreeView1.Selected,'Neue Notiz'); //füge Node hinzu
    myNode.Data := Pointer(fileNode); //markiere Node als fileNode
  end;
end;

procedure TForm1.FolderButton1Click(Sender: TObject);
begin
  if TreeView1.Items.Count<>0 then
  begin
    if Integer(TreeView1.Selected.Data) <> fileNode then //Der ausgewählte Node darf kein fileNode sein
    begin
      myNode :=  TreeView1.Items.AddChild(TreeView1.Selected,'Neuer Ordner'); //füge Node hinzu
      myNode.Data := Pointer(folderNode); //markiere Node als folderNode
    end;
  end
  else
  begin
    myNode :=  TreeView1.Items.AddChild(TreeView1.Selected,'Neuer Ordner'); //füge Node hinzu
    myNode.Data := Pointer(folderNode); //markiere Node als folderNode
  end;
end;


Danke! :D


Coder - So 17.10.04 19:28

Es gibt doch noch einen kleinen Fehler:
Nachdem man das Erste Item erstellt hat muss man es nochmal selektieren bevor man ein anderes erstellt sonst gibt es eine Zugriffsverletzung.

Wie kann ich das gerade erstellte Item selectieren? Aus der Hilfe werd ich nicht schlau. :?


BenBE - So 17.10.04 22:51

Ich würd mal auf Treeview1.Selected := XY tippen ...
Aber sicherlich hat die VCL da was degegen.

Probier mal ein Perform(WM_Click) mit den entsprechenden Koordinaten, falls ersteres nicht geht.


Coder - Mo 18.10.04 13:59

:shock: mir zu kompliziert :mrgreen:

Ich habs jetzt so gemacht, das gleich beim Programmstart ein Knoten da ist. :wink:

Trotzdem Danke!


SevenValues - So 07.11.04 20:26

Hi!
Hab mir Euren Dialog mal durchgelesen und es hat mich zwei Schritte vorwärts gebracht. Danke dafür.

Mal was anderes zum selben Thema:

Wenn ich Informationen zum fileNode - also sprich: zum letzten Eintrag im Zweig speichern will, kann ich zum einen durchaus ein Memofeld nehmen, allerdings gefällt mir diese Möglichkeit ganz und gar nicht, denn bei meinem Prog beziehe ich die besagten Informationen aus einer ini, die ich dann ja gleich ins Memofeld laden könnte, was ich nicht will. So bin ich auf die Idee gekommen meine Infos einfach in ein zweidimensionales String-Array zu schreiben, wenn ich eh alles aus der ini lade. Allerdings gefällt mir diese Möglichkeit genausowenig, wie das mit dem Memofeld. Hat jemand von Euch ne Idee, wie ich sechs verschiedene Informationen pro fileNode wärend des Programmablaufs speichern kann und zwar so - daß ich keines Falls mehr irgendwelche Ladevorgänge durchlaufen muß?? Denn schaut Euch mal meine Laderoutine an - da kriegt Ihr nen Steifen:

Delphi-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:
procedure TForm1.FormCreate(Sender: TObject);
var
      i, j, k, l           :     integer;
      entries              :     integer;
      TN, TN2, TN3, TN4    :     TTreeNode;
      Entry, Entry2        :     string;
begin
      TreeView1.Items.Clear;
      Load:=TIniFile.Create(ExtractFileDir(Application.ExeName)+'\popup.ini');
      SetLength(Infos,Load.ReadInteger('startup','entries',-1));
      for i:=0 to Length(Infos)-1 do begin
         SetLength(Infos[i],6);
      end;
      entries:=Load.ReadInteger('createsubmenues','entries',-1);
      TN:=TreeView1.Items.AddFirst(Nil,'PopUp');
      TN.Data:=Pointer(folderNode);
      for i:=1 to entries do begin
         Entry:=Load.ReadString('createsubmenues',inttostr(i),'--??--');
         TN2:=TreeView1.Items.AddChild(TN,Entry);
         TN2.ImageIndex:=1;
         TN2.SelectedIndex:=3;
         TN2.Data:=Pointer(folderNode);
         For j:=1 to Load.ReadInteger(Entry,'entries',-1do begin
            Entry2:=Load.ReadString(Entry,inttostr(j),'--??--');
            TN3:=TreeView1.Items.AddChild(TN2,Entry2);
            TN3.ImageIndex:=1;
            TN3.SelectedIndex:=3;
            TN3.Data:=Pointer(folderNode);
            for k:=1 to Load.ReadInteger('startup','entries',-1do begin
               Application.ProcessMessages;
               if Entry2=Load.ReadString('entry'+inttostr(k),'subitemname','--??--'then begin
                  TN4:=TreeView1.Items.AddChild(TN3,Load.ReadString('entry'+inttostr(k),'caption','--??--'));
                  TN4.Data:=Pointer(fileNode);
                  Infos[k-1,0]:=Load.ReadString('entry'+inttostr(k),'caption','--??--');
                  Infos[k-1,1]:=Load.ReadString('entry'+inttostr(k),'programm','--??--');
                  Infos[k-1,2]:=Load.ReadString('entry'+inttostr(k),'parameter','--??--');
                  Infos[k-1,3]:=Load.ReadString('entry'+inttostr(k),'directory','--??--');
                  Infos[k-1,4]:=Load.ReadString('entry'+inttostr(k),'window','--??--');
                  Infos[k-1,5]:=inttostr(TN4.AbsoluteIndex);
                  TN4.ImageIndex:=2;
                  TN4.SelectedIndex:=2;
                  TreeView1.Items.Item[0].Expand(false);
               end;
            end;
         end;
      end;
end;


Liebe Grüße
7

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.