Kommunikation zwischen Forms (Delegate + Event ?)



  • Hallo,

    ich habe folgendes Problem und nach gründlicher Recherche im Netz und zig Versuchen C# Code in C++/CLI zu ändern hoffe ich hier auf Hilfe (bitte bitte).

    Folgendes Problem:

    Form1 = Mainform (mit #include "Form2.h")
    Form2 = Subform die von Mainform über einen Button_Click aufgerufen wird (instanziert heißt das oder?)

    Aufgabe: Beim Schließen von Form2 soll ein Wert (Boolean/String.. egal..) an Form1 zurückgegeben werden.

    Will eigentlich auch keine globalen Variablen benutzen nachdem ich mich seit Stunden durch Delegaten und Ereignisse gegraben habe.

    Soviel ich verstanden habe ist es möglich, beim Erstellen der Form2 von Form1 aus einen Ereignishandler(Heißt so oder?) zu bauen, der das Ereignis (welches dann in Form2 stattfindet) abonniert.

    Nur weiß ich nicht genau wie das funktioniert bzw. wo der Delegat (oder das event?) deklariert wird und überhaupt.

    Bin für jede Hilfe dankbar.



  • Mach im Form2 einfach ein public property. Dies fragst Du nach dem Schliessen ab...

    Form2^ frm = gcnew Form2();
    frm->ShowDialog();
    int WertImForm = frm->MeinProperty;
    

    PS: Falsches Forum.. besser wäre C++/CLI



  • Danke erstmal - ich probiers aus.

    Nur warum klappt das so nicht

    // Hier ist der wesentliche Ausschnitt aus Form 1, welche unten eine Form21 (Subform) erstellt
    
    void OK() {MessageBox::Show("OK!");}
    
    public: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
             {
    		Form21 ^F2 = gcnew Form21;
    		F2->EVT += gcnew EVThandler(this,&Form1::OK); 
    	}
    

    Und Form 2:

    public delegate void EVThandler();
    
    namespace thisOne {
    
    	public ref class Form21 : public System::Windows::Forms::Form
    	{
              event EVThandler^ EVT;
    
    //...
    
    private: System::Void Form21_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
    			 EVT();
    
    			 }
    

    Das wird alles kompiliert (habs auch nicht geglaubt!) - leider funzt der Aufruf der Methode OK nicht.



  • Wo wird denn Dein Form aufgemacht?
    Warum willst Du einen Event?



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum C++/CLI mit .NET verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • hi,

    also ich hab sowas letztens so gelöst, dass ich in Form2 eine public funktion eingebaut habe, die einen in Form2 zugewiesenen Wert zurückgibt.

    //Form1
    
    ...
    Form2 ^fm2 = gcnew Form2();
    fm2->ShowDialog();
    
    int wert = fm2->getWert();
    
    //Form2
    
    ...
    int wert = 5;
    
    ...
    
    public: int getWert()
    {
    return wert;
    }
    

    So hats bei mir gut funktioniert und Du hast weiterhin eine funktionierende Kapselung...

    Grüße Solick



  • Konnte gar nicht klappen. Form2 wird schließlich noch gar nicht angezeigt 😡 !! Danke für eure Hilfe. Der Vollständigkeit halber und weils im ganzen Netz (so hab ich den Eindruck) nur C# Code zu dem Problem gibt, nochmal der Code:

    // Hier ist der wesentliche Ausschnitt aus Form 1, welche unten eine Form21 (Subform) erstellt
    
    #include "Form21.h"
    //....
    public ref class Form1 : public System::Windows::Forms::Form
    
    void OK() {MessageBox::Show("OK!");}
    
    public: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
             {
    		Form21 ^F2 = gcnew Form21;
    		F2->EVT += gcnew EVThandler(this,&Form1::OK); 
    
    /*Fehlende Zeile: */  F2->ShowDialog();
    	}
    

    Und Form 2:

    public delegate void EVThandler();
    
    namespace thisOne {
    
    	public ref class Form21 : public System::Windows::Forms::Form
    	{
              event EVThandler^ EVT;
    
    //...
    
    private: System::Void Form21_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
    			 EVT();
    
    			 }
    


  • und weils im ganzen Netz (so hab ich den Eindruck) nur C# Code zu dem Problem gibt,

    Ja huiiii, der wäre ja dann extrem schwer zu portieren.
    Simon

    Edit: Lies mal Grundlagen zum Thema "Events mit .NET" ...



  • Ja huiiii, der wäre ja dann extrem schwer zu portieren.
    Simon

    Kann ja sein, dass es für dich Profi unheimlich leicht ist. Machen wir doch einfach ein Forum "C-Alles" - reicht ja dann.

    Edit: Lies mal Grundlagen zum Thema "Events mit .NET" ...

    Und wie glaubst du hab ich den obigen Code hinbekommen? Geraten ??? Bestimmt nicht. Delegate und Events sind nicht gerade die einfachste Syntax - und obwohl der Code funzt, versteh ich die Struktur immer noch nicht zu 100% - und darum gings in diesem Post.

    Ganz ehrlich, ich versteh Kommentare wie deinen nicht. Aber vielleicht fühlst dich dann toll dabei. 🙄



  • Konnte gar nicht klappen. Form2 wird schließlich noch gar nicht angezeigt

    Wie äussert sich das Fehlverhalten (Compiler, Laufzeit, ...)?

    Beim feuern des Events ( EVT();) brauchts noch einen Check:

    private: System::Void Form21_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e)
             {
                 if (nullptr != EVT)
                 {
                    EVT();
                 }
             }
    


  • In C++/CLI nicht 😉



  • Hallo Theta,

    Compiler zeigte gar nichts an und lief durch. Während das Programm lief wurde die Methode 'OK' nicht ausgeführt, gab aber keinen Absturz. Ist auch logisch: Wenn Form2 nicht offen ist, kann sie auch nicht geschlossen werden und dann feuert sie auch kein Ereignis.

    Danke für den Tip mit dem Check. 👍



  • Danke für den Tip mit dem Check

    Welcher offenbar falsch ist... naja, Schaden tuts nicht.



  • public delegate void MyEventHandler();
    
    // in ref class Form2
    public: event MyEventHandler^ MyEvent;
    
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
    			 MyEvent();
    		 }
    
    // in ref class Form1
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
    			 Form2 form2;
    			 form2.MyEvent += gcnew MyEventHandler(this, &Form1::OnMyEvent);
    			 form2.ShowDialog();
    		 }
    
    		 void OnMyEvent()
    		 {
    		 }
    

    Simon

    Edit: Funktioniert auch mit dem FormClosing Event.



  • Nur: Warum so kompliziert! Man braucht keinen Event um mitzubekommen, dass der Dialog geschlossen wurde... er ist geschlossen, wenn die ShowDialog-Methode zurückkehrt...



  • Jochen Kalmbach schrieb:

    Nur: Warum so kompliziert! Man braucht keinen Event um mitzubekommen, dass der Dialog geschlossen wurde... er ist geschlossen, wenn die ShowDialog-Methode zurückkehrt...

    Wenn ich nun aber statt ShowDialog() die Methode Show() benutze, bspw. für ein Drag&Drop zwischen den Forms, dann läuft der Code leider durch und bekommt nichts zurück.
    Ich denke mit den Events bin ich da variabler oder?



  • Ja, wenn das Wörtchen wenn nicht wäre....

    Es ist sehr ungewöhnlich dies zu machen, wann man ShowDialog verwendet...


Anmelden zum Antworten