Frame ändern bei Klick auf Eintrag in TreeView
-
nein
dein Frame ist wirklich noch mit TFrame benannt?
mal als Beispiel: ein neues Framesclass 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.