Frame ändern bei Klick auf Eintrag in TreeView



  • nein

    dein Frame ist wirklich noch mit TFrame benannt?
    mal als Beispiel: ein neues Frames

    class TMyFrame : public TFrame
    

    dann folgt daraus:

    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
    {
       if (TreeView1->Selected != 0) {
          if (TreeView1->Selected->Text == "A") {
             TMyFrame * fra = new TMyFrame(this); // <-- hier muß deine Frameinstanz erzeugt werden !!
             fra->Parent = this;
             fra->Left = 150;
             fra->Top = 50;
             fra->Visible = true;
          }
       }
    


  • ja ok, das funktioniert. Wenn ich auf den 1. Eintrag klicke wird in der Form der Frame angezeigt. Beim Klick auf den 2. Eintrag erscheint auch der 2. Frame.
    Wenn ich dann aber ein zweites Mal auf den 1. oder 2. Eintrag im Treeview klicke, kommt ein EKomponentError, dass die Komponente bereits existiert.



  • Hast du den gleichen Code wie bei Linnea?
    Setzt du einen Namen für dein Frame?
    Solltest du den alten Frame nicht erstmal entfernen bevor du einen neuen einfügst?



  • hier mein Code:

    void __fastcall TForm1::TreeView1Click(TObject *Sender)
    {
       if (TreeView1->Selected != 0) {
          if (TreeView1->Selected->Text == "A") {
             TfraElement1* fraElement1 = new TfraElement1(this);
             fraElement1->Parent = this;
             fraElement1->Left = 150;
             fraElement1->Top = 50;
             fraElement1->Visible = true;
          }
          if (TreeView1->Selected->Text == "B") {
             TfraElement2* fraElement2 = new TfraElement2(this);
             fraElement2->Parent = this;
             fraElement2->Left = 150;
             fraElement2->Top = 50;
             fraElement2->Visible = true;
          }
       }
    }
    

    Die beiden Frames hab ich über "Datei-->NeuerFrame" angelegt und gespeichert. Hier der Code von frameElement1.h:

    class TfraElement1 : public TFrame
    {
    __published:	// Von der IDE verwaltete Komponenten
       TButton *Button1;
       TButton *Button2;
       TButton *Button3;
    private:	// Anwender-Deklarationen
    public:		// Anwender-Deklarationen
       __fastcall TfraElement1(TComponent* Owner);
    };
    


  • Warum willst du eigentlich die Frames immer wieder neu erzeugen?
    Du könntest doch Zeiger auf deine Frames als Member deiner Form speichern, so dass du einfach darauf zugreifen kannst.



  • ja ok, das seh ich ein. Ich muss nur wenn ich das Element1 ein zweites Mal anklicke, das Element 2 unsichtbar machen, da es sonst vom 2. Frame überdeckt wird. Aber so funktioniert es.

    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
       TTreeView *TreeView1;
       void __fastcall TreeView1Click(TObject *Sender);
    private:	// Anwender-Deklarationen
       TfraElement1* frameElement1;
       TfraElement2* frameElement2;
    public:		// Anwender-Deklarationen
       __fastcall TForm1(TComponent* Owner);
    };
    
    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
    {
       fraElement1 = new TfraElement1(this);
       fraElement2 = new TfraElement2(this);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::TreeView1Click(TObject *Sender)
    {
       if (TreeView1->Selected != 0) {
          if (TreeView1->Selected->Text == "A") {
             fraElement1->Parent = this;
             fraElement1->Left = 150;
             fraElement1->Top = 50;
             fraElement1->Visible = true;
             fraElement2->Visible = false;
          }
          if (TreeView1->Selected->Text == "B") {
             fraElement2->Parent = this;
             fraElement2->Left = 150;
             fraElement2->Top = 50;
             fraElement2->Visible = true;
             fraElement1->Visible = false;
          }
       }
    }
    

    Da ich in meinem Programm ca. 40 Frames habe, die über den TreeView nach oben gezeigter Methode umgeschaltet werden, muss ich in jeder if-Schleife alle anderen 39 Frames mit Visible = false unsichtbar machen. Das wird dann ja ein sehr langer Code. Wie kann ich das besser machen bzw gibts eine effizientere Methode?



  • Hallo

    Erstell ein zusätzliches Array von deines Frames (Siehe FAQ, dynamische Arrays von Komponenten), dann kannst du die Frames mit Indexen ansprechend und die "Schaltlogik" verallgemeinern.

    bis bald
    akari



  • die Frames haben doch aber immer einen anderen Typ TfraElement1*, TfraElement2*, usw. Die Elemente in einem DynamicArray müssen doch den gleichen Typ haben.



  • Hallo

    Aber bei der Zusammenarbeit mit deinem TreeView benutzt du auch nur die Eigenschaften eines TFrames. Also kann dein Container die Basisklasse TFrame verwenden, um Parent, Left, Top oder Visibke anzusprechen. Und du kannst trotzdem Zeiger auf beliebige von TFrame abgeleitete Instanzen in den Container legen.

    Erst wenn du über TFrame weiter hinausgehende Gemeinsamkeiten nutzen willst, mußt du dann zusätzliche Lösungen finden, wie zum Beispiel eine eigene polymorphe Basisklasse als Interface.

    bis bald
    akari



  • class TForm1 : public TForm
    {
    __published:    // Von der IDE verwaltete Komponenten
       TTreeView *TreeView1;
       void __fastcall TreeView1Click(TObject *Sender);
    private:    // Anwender-Deklarationen
        TfraElement1* frameElement1;
        TfraElement2* frameElement2;
        //usw. bis fraElement40;
        int numFrames;
        DynamicArray<TFrame*>aFrames; //Deklaration des dyn. Arrays für die Frames
    public:        // Anwender-Deklarationen
       __fastcall TForm1(TComponent* Owner);
    };
    
    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner),
         numFrames(40)
    {
        fraElement1 = new TfraElement1(this);
        fraElement2 = new TfraElement2(this);
         //usw. bis fraElement40;
    
        aFrames.Length = numFrames;
        for (int i=0; i<aFrames.Length; i++) {
            aFrames[i] = new TFrame(this);
            aFrames[i].Parent = this;
            aFrames[i].Left = 150;
            aFrames[i].Top = 50;
        }
    }
    

    Nun muss ich aber doch meine erzeugten Frames irgendwie noch in das Array legen. Die sind immer anders bezeichnet. Element1, Element2 usw war nur beispielhaft. Wie mach ich das?



  • Du brauchst doch hier nur das Array. Lass die separaten Membervariablen weg und belege dein Array mit den konkreten Klassen.
    etwa so

    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner),
         numFrames(40)
    {
        aFrames[1] = new TfraElement1(this);
        aFrames[1]->Parent = this;
        aFrames[1]->Left = 150;
        aFrames[1]->Top = 50;    
        aFrames[2] = new TfraElement2(this);
         //usw. bis fraElement40;
    
    // das hier ist Unsinn, weg damit
        //aFrames.Length = numFrames;
        //for (int i=0; i<aFrames.Length; i++) {
        //    aFrames[i] = new TFrame(this);
        //    aFrames[i].Parent = this;
        //    aFrames[i].Left = 150;
        //    aFrames[i].Top = 50;
        //}
    }
    

    Ich würde statt dem DynamicArray lieber std::vector nehmen, aber das ist wohl Geschmackssache.


Anmelden zum Antworten