Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Frage zur TreeView (https://www.delphipraxis.net/29304-frage-zur-treeview.html)

Akut-Programming 7. Sep 2004 12:57


Frage zur TreeView
 
Hi,

ich will in meiner TreeView erst alle "Hauptknoten" hinzufügen (klappt auch schon) und dann die einzelnen Childs. Die Daten hole ich aus einer MySQL DB. Wenn ich nun die Hauptknoten angelegt habe, wie bekomme ich dann noch eine genaue Zuordnung hin?:gruebel: Bsp: In der einen Tabelle habe ich die Hauptknoten stehen z.b: "Autos" und "Motoräder". In einer anderen Tabelle stehen die Items, die dann als Child eingefügt werden sollen. Diese Tabelle hat auch eine Spalte "GroupID" über die ich dann einen Bezug auf z.B. "Autos" herstelle. Da dies das erste mal ist, wo ich mit einer TreeView arbeite, bin ich da jetzt etwas ratlos. :wall: - Die Delphi-Hilfe brachte mir auch keinen Erfolg. Ich hoffe, mein Anliegen ist verständlich erklärt!?

Gruß,

andianon 7. Sep 2004 13:10

Re: Frage zur TreeView
 
Idealerweise hast du Objekte, z.B. auf Basis der Klasse "TAuto". Diese Klasse enthält als Attribut die GruppenID. Das erzeugt Objekt referenzierst du mit in dem Knoten. Ab jetzt musst du nur noch den Knoten mit dem Objekt der entsprechenden GruppenID suchen und an diesem einen neuen Knoten erzeugen über den du z.B. das Objekt "VW Golf 3..." referenzierst.

Oder für quick'n'dirty: Merk dir den AbsoluteIndex bzw. Index von TTreeNode, den du für "Autos" anlegst und hang alle einzelnen Autos an den Knoten mit diesem AbsoluteIndex. ACHTUNG: Eingefügte Knoten verschieben den Index.

Gruß Andi

ibp 7. Sep 2004 13:10

Re: Frage zur TreeView
 
es macht mehr sinn, wenn du erst einen hauptgruppenzweig erstellst und dann alle dazugehörigen kindknoten.... dann den zweiten hauptgruppenzweig etc

andianon 7. Sep 2004 13:12

Re: Frage zur TreeView
 
Da hat mein Vorgänger definitiv Recht!
Ein Baum schreit förmlich danach den Weg bis zum Leaf durchzugehen.

Gruß Andi

Akut-Programming 7. Sep 2004 14:37

Re: Frage zur TreeView
 
ich habs mal versucht umzusetzen..
Delphi-Quellcode:
procedure TfrmMain.GetObjects();
var
   ListItem: TTreeNode;
   i: integer;
   AktGroup: Integer;
begin
     lvProjekte.Items.Clear;

     dsGetObjects.Active:=false;
     dsGetObjects.CommandText:='select * from objects_tbl';
     dsGetObjects.Active:=true;
     dsGetObjects.First;

     for i:=0 to dsGetObjects.RecordCount -1
     do begin
        AktGroup:=dsGetObjects.Fields.Fields[1].AsInteger;
        if dsGetObjects.Fields.Fields[1].AsInteger = AktGroup
        then begin
             if dsGetObjects.Fields.Fields[1].AsInteger <> AktGroup
             then AktGroup:=dsGetProjects.Fields.Fields[1].AsInteger;
             dsGetGroupID.Active:=false;
             dsGetGroupID.CommandText:='select bezeichnung from groups_tbl where id= '''+IntToStr(AktGroup)+'''';
             dsGetGroupID.Active:=true;
              with lvObjects.Items
              do begin
                 ListItem := Add(nil, dsGetGroupID.Fields.Fields[0].AsString);
                 AddChild(ListItem, dsGetObjects.Fields.Fields[2].AsString);
              end;
              dsGetProjects.Next;
        end;
     end;
end;
Er setzt zwar die Einträge nach Anzahl der Daten im recordcount, aber er wählt nicht das nächste Obejekt, welches in einer anderen Gruppe stehen würde.

ibp 7. Sep 2004 14:59

Re: Frage zur TreeView
 
überprüfe deinen code nochmal...


Code:
Schritte:

1. hole alle gruppen
2. nimm 1. datensatz aus der gruppe
3. erstelle einen baumknoten gruppe
4. holle alle daten die zur gruppe gehören
5. nimm 1.datensatz aus untergruppe
6. erstelle einen kindknoten zur aktuellen gruppe
7. nächster datensatz aus untergruppe
8. weiter bei 6. solange noch datensätze vorhanden sind
9. nächster datensatz aus gruppe
10. weiter bei 3. solange noch datensätze vorhanden sind

Akut-Programming 8. Sep 2004 08:11

Re: Frage zur TreeView
 
Nice!! :lol: - Ich hab mich da jetze mal rangesetzt, da ich gestern noch an nem anderen Projekt weiter arbeiten musste.. es funzt endlich! Dank dir ibp. :thumb:

Delphi-Quellcode:
procedure TfrmMain.GetObjects();
var
   ListItem: TTreeNode;
   i, i2: integer;
begin
     lvObjects.Items.Clear;

     //Alle Gruppenbezeichnungen laden
     dsGetGroupID.Active:=false;
     dsGetGroupID.CommandText:='select * from groups_tbl';
     dsGetGroupID.Active:=true;
     //Ersten Datensatz auswählen
     dsGetGroupID.First;
     //Baumknoten erstellen - Solange wiederholen, wie Gruppen vorhanden sind
     for i:=0 to dsGetGroupID.RecordCount -1
     do begin
        with lvObjects.Items
        do begin
           ListItem := Add(nil, dsGetGroupID.Fields.Fields[1].AsString);
        end;
        //Alle Objekte zur Gruppe laden
        dsGetObjects.Active:=false;
        dsGetObjects.CommandText:='select * from Objects_tbl where groupid = '''+dsGetGroupID.Fields.Fields[0].AsString+'''';
        dsGetObjects.Active:=true;
        //Erstes Objekt wählen
        dsGetObjects.First;
        //Child erstellen - Solange wie Daten vorhanden sind
        for i2:=0 to dsGetObjects.RecordCount -1
        do begin
           with lvObjects.Items
           do begin
              AddChild(ListItem, dsGetObjects.Fields.Fields[2].AsString);
           end;
           //Nächstes Objekt wählen
           dsGetObjects.next;
        end;
        //Nächste Gruppe wählen
        dsGetGroupID.next;
     end;
end;
Gruß,

Akut-Programming 8. Sep 2004 11:57

Re: Frage zur TreeView
 
Nun hab ich mal weiter geproggt.. ich bin nun beim einfügen eines neuen Objektes angekommen. Wenn das Objekt eingefügt wurde, wollt ich die Liste neu laden lassen. Jedoch lädt er mir jetzt nur noch die Gruppen und nicht die dazugehörigen Objekte obwohl ich die selbe Prozedur (siehe oben) aufrufe. :gruebel: Kann mir da vielleicht jemand sagen, woran das liegt?

Gruß,

ibp 8. Sep 2004 12:03

Re: Frage zur TreeView
 
warum willst du denn den baum neu laden, wenn er schon vorhanden ist?

Akut-Programming 8. Sep 2004 12:05

Re: Frage zur TreeView
 
Zitat:

Zitat von ibp
warum willst du denn den baum neu laden, wenn er schon vorhanden ist?

:gruebel: Weil ich ein neues Objekt in die Datenbank eingefügt habe und der Nutzer die Anwendung nicht neu starten soll, um die aktuellen Daten zu sehen!! :zwinker:

ibp 8. Sep 2004 12:15

Re: Frage zur TreeView
 
... dann füge das neue objekt doch gleichzeitig an die richtige gruppe an...

immer wieder neu aufbauen ist bei ein paar daten sicher kein problem, aber wenn du sehr viele daten hast, dann bedeutet das schon eine nervige zeitverzögerung. hatte mal das gleiche problem gelöst habe ich es so, dass sogar am anfang der baum nicht ganz auggbaut wird, sondern nur bis zum jeweiligen sichtbaren level.

schreib dir doch eine funktion die die objekte einfügt, der übergibst du den zugehörigen gruppenknoten und bekommst zurück den neuen kindknoten (ist sinnvoll, wenn du noch weitere ebenen aufbauen willst ansonsten reicht eine prozedur)
diese funktion/prozedur kannst du auch in dein bisheriges einbinden!

gruß rené

Akut-Programming 8. Sep 2004 12:20

Re: Frage zur TreeView
 
Zitat:

Zitat von ibp
schreib dir doch eine funktion die die objekte einfügt, der übergibst du den zugehörigen gruppenknoten und bekommst zurück den neuen kindknoten (ist sinnvoll, wenn du noch weitere ebenen aufbauen willst ansonsten reicht eine prozedur)
diese funktion/prozedur kannst du auch in dein bisheriges einbinden!

gruß rené

hmm kannste mir mal vielleicht n code schnipsel geben?? Ich habe ja überlegt die treeView nach dem Gruppennamen zu durchsuchen. Nur leider weiß ich auch nicht wies geht... Wenn ich anstatt der Gruppennamen Gruppen IDs im Baum anzeigen würde, könnte ich ja über den index gehen, nur das ist leider nicht so. :| - Ich müsste irgendwie auf den Node kommen, zu dem ich das eigentliche Objekt eingefügt habe!?

Akut-Programming 8. Sep 2004 12:57

Re: Frage zur TreeView
 
Okay ich hab die Lösung...
Delphi-Quellcode:
           Node := frmMain.lvObjects.Items[0];
           While ( Node <> Nil )
           Do Begin
              If ( Node.Text = cbGruppe.Text ) Then Break;
              Node := Node.GetNextSibling; // holt den Verwandten auf der gleichen Ebene
           End;
           If ( Assigned(Node) ) Then frmMain.lvObjects.Items.AddChild(Node, edBezeichnung.Text);
Gruß,

Akut-Programming 9. Sep 2004 10:32

Re: Frage zur TreeView
 
Nun hab ich noch ein kleines Problem.. hier ist erstmal der Code:
Delphi-Quellcode:
procedure TfrmMain.lvObjectsClick(Sender: TObject);
var
   ListItem: TListItem;
   i, i2, GroupID: integer;
   ListFilled: Boolean;
begin
     lvObjectdata.Items.Clear;

     //Alle Objects zur Gruppe in einer ListView anzeigen
     if lvObjects.Selected.HasChildren=true
     then begin
          dstGetAllObjects.Active:=false;
          dstGetAllObjects.CommandText:='select id from groups_tbl where bezeichnung = '''+lvObjects.Selected.Text+'''';
          dstGetAllObjects.Active:=true;
          GroupID:=dstGetAllObjects.Fields.Fields[0].AsInteger;
          if dstGetAllObjects.RecordCount <>0
          then begin
               for i := 0 to dstGetAllObjects.RecordCount-1
               do begin
                  //Alle Objekte anzeigen, wenn er Admin ist
                  if frmLogin.IsAdmin='ja'
                  then begin
                       dstGetAllObjects.Active:=false;
                       dstGetAllObjects.CommandText:='select * from Objects_tbl where groupid = '''+IntToStr(groupid)+'''';
                       dstGetAllObjects.Active:=true;
                       dstGetAllObjects.First;

                       ListItem := lvObjectdata.Items.Add;
                       ListItem.Caption :=dstGetAllObjects.Fields.Fields[0].AsString;
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[1].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[2].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[3].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[4].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[5].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[6].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[7].AsString);
                       dstGetAllObjects.Next;
                       ListFilled:=true;
                  end else
                  //Nur die Objekte anzeigen, die er erstellt hat
                  if frmLogin.IsAdmin='nein'
                  then begin
                       dstGetAllObjects.Active:=false;
                       dstGetAllObjects.CommandText:='select * from Objects_tbl where groupid = '''+IntToStr(groupid)+''' and creator like '''+frmLogin.UserID+'''';
                       dstGetAllObjects.Active:=true;
                       dstGetAllObjects.First;

                       ListItem := lvObjectdata.Items.Add;
                       ListItem.Caption :=dstGetAllObjects.Fields.Fields[0].AsString;
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[1].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields[2].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[3].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[4].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[5].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[6].AsString);
                       ListItem.SubItems.Add(dstGetAllObjects.Fields.Fields[7].AsString);
                       dstGetAdminstatus.Next;
                  end;
               end;
          end;
     end;

     //Einzelnes Object anzeigen
     dstGetObjectData.Active:=false;
     dstGetObjectData.CommandText:='select * from Objects_tbl where bezeichnung = '''+lvObjects.Selected.Text+'''';
     dstGetObjectData.Active:=true;
     dstGetObjectData.First;
     if dstGetObjectData.RecordCount <>0
     then begin
          tbsToDo.Enabled:=true;
          tbsWhatsNew.Enabled:=true;
          tbsObjectdateien.Enabled:=true;
          for i := 0 to dstGetObjectData.RecordCount -1
          do begin
             ListItem := lvObjectdata.Items.Add;
             ListItem.Caption :=dstGetObjectData.Fields.Fields[0].AsString;
             ListItem.SubItems.Add(dstGetObjectData.Fields.Fields[1].AsString);
             ListItem.SubItems.Add(dstGetObjectData.Fields.Fields[2].AsString);
             ListItem.SubItems.Add(dstGetObjectData.Fields.Fields[3].AsString);
             ListItem.SubItems.Add(dstGetObjectData.Fields.Fields[4].AsString);
             ListItem.SubItems.Add(dstGetObjectData.Fields.Fields[5].AsString);
             ListItem.SubItems.Add(dstGetObjectData.Fields.Fields[6].AsString);
             ListItem.SubItems.Add(dstGetObjectData.Fields.Fields[7].AsString);
             dstGetObjectData.Next;
          end;
     end;
end;
Das Problem ist nun, ich frage einer Seits ab, ob der User den Status 'Admin' hat - wenn ja, soll er alle Objekte zu den Gruppen angezeigt bekommen. Ist er nicht Admin, wird abgefragt ob er der Ersteller des Objekts ist ('Creator') und soll somit nur die angezeigt bekommen, die er eingetragen hat. - In diesem Fall bekomme ich die Gruppen angezeigt, und auch die Objekte werden dann jeweils untergeordnet, in sofern er schon welche angelegt hat. Nun will ich es so machen, das wenn auf eine Gruppe geklickt wird, erstmal alle Objekte & ihre Daten in einer weiteren ListView angezeigt werden. Ist der User Admin, sollen eben alle erstmal in der ListView angezeigt werden.. aber wenn er der Ersteller ist, nur die, die er erstellt hat. - Es stehen aber nur die jeweiligen Objekte als Child in der TreeView und ich müsste jedes einzelne anklicken, um die Objektdaten einzusehen. Ich finde leider keinen Fehler in meinem Code, warum das nicht klappt - Kann mir jemand vielleicht sagen, wo ich meinen Denkfehler habe?? :gruebel:

Gruß,


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:30 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-2025 by Thomas Breitkreuz