Datenaustausch zwischen zwei Forms



  • Hallo,

    Mein Problem ist folgendes:

    Ich habe zwei Forms (Form1 und Form2). Form2 wird von Form1 aufgerufen,
    in Form2 werden dann Daten (z.B. ein String) eingegeben. Diese Daten werden
    an Form1 weitergegeben, dann wird Form2 geschlossen.

    Im Netz habe ich dieses Beispiel für C# gefunden:

    [url]
    http://www.tutorials.de/forum/net-tutorials/185977-c-datenaustausch-zwischen-zwei-forms.html
    [/url]

    Ich habe dann folgendes gemacht:

    in der Klassendefinition von Form1 einen String definiert:

    public: String ^form1_str;
    

    Diesen String im Konstruktor von Form1 initialisiert:

    this->form1_str = "";
    

    In der Klassendefinition von Form2 habe ich eine Variable für die Referenz
    zu Form1 deklariert:

    private: Form1 form1;
    

    Den Konstruktor von Form2 habe ich so geändert:

    public: Form2(Form1 f)
    	{
    		InitializeComponent();
    		this->form1 = f;
    	}
    

    In einer Funktion von Form2 fülle ich dann form1_str:

    this->form1.form1_str = "test";
    

    Und so rufe ich dann Form2 in Form1 auf:

    Form2 ^f2 = gcnew Form2(this);
    f2->ShowDialog();
    this->label1->Text = this->form1_str;
    

    Jetzt dachte ich, dass in label1 "test" steht, aber ich bekomme folgende
    Fehler beim Übersetzen:

    1. error C2582: 'operator =' function is unavailable in 'mein_project::Form1'
    2. error C2664: 'mein_project::Form2::Form2(mein_project::Form1)' : cannot convert parameter 1 from 'mein_project::Form1 ^const ' to 'mein_project::Form1'
    No user-defined-conversion operator available, or
    No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

    Wäre wirklich dankbar, wenn mir jemand einen Tip geben könnte.



  • Der Quellcode passt irgendwie nicht ganz zum Problem.

    Erst mal mach aus dem

    private: Form1 form1;
    

    ein

    private: Form1 ^ form1;
    

    und aus dem

    public: Form2(Form1 f)
        {
            InitializeComponent();
            this->form1 = f;
        }
    

    ein

    public: Form2(Form1 ^f)
        {
            InitializeComponent();
            this->form1 = f;
        }
    

    Woher jetzt das const bei der Form kommt kann man hier nicht erkennen. Dazu mal quellcode posten. Hart und nicht herzlich wäre ein const_cast<Form1^> , aber das passt nich so ganz mit Problem und Quellcode.



  • Danke. Jetzt funktioniert es.

    Mal ne andere Frage:

    Realisiert man den Datenaustausch zwischen zwei Forms normalerweise auf diese Weise?
    Also der aufgerufenen Form eine Referenz der aufrufenden Form mitgeben, damit man auf deren Variablen direkt zugreifen kann?



  • ka, es gibt sicherlich Methoden die über Messagequeues arbeiten. Ebenso würde ich mir sorgen wegen Threadsicherheit machen, das Thema hab ich nie angefasst aber immer Angst vor wenn ich was schreibe.

    Eventuell kann Jochen etwas dazu sagen und hat einen Link oder Stichworte auf Lager wie man sowas in .net schön lösen könnte. Wäre prima 🙂



  • philosoph schrieb:

    Realisiert man den Datenaustausch zwischen zwei Forms normalerweise auf diese Weise?
    Also der aufgerufenen Form eine Referenz der aufrufenden Form mitgeben, damit man auf deren Variablen direkt zugreifen kann?

    Eigentlich sollte man nicht auf "Variablen" (heissen eigentliche "Fields") direkt zugreifen, sondern sollte dies über "Properties" lösen. Aber vom Weg her ist es schon so ok.

    Ich persönlich würde nur die Daten übergeben, welche das neue Form braucht und beim beenden wieder die Rückgabedaten auslesen. ALso nicht immer das ganze Form übergeben, das ist doch etwas unschön.



  • Wann muss man sich gedanken wegen der Threadsicherheit machen ?
    Kann man davon ausgehen, das wenn man keinen Thread mit der "Hand" startet, alles Threadsicher ist oder muss man davon ausgehen, das die Dialoge und deren Daten in unterschiedlichen Threads laufen können ?

    *keine ahnung von hab, passt aber ins Thema 🤡*



  • Wenn Du keine Threads startest und auch keine Klassen verwendest, welche Threads erzeugen, brauchst Du Dir keine Gedanken machen (bzw. musst keinen Aufwand treiben).
    Ansonsten darfst Du natürlich nie UI-Elemente/Properties aus einem anderen Thread aufrufen, als den mit dem sie erzeugt wurden.



  • Sitz hier gerade am gleichen Problem...
    Nur irgendwie will das nicht funktionieren und ich versteh nicht warum?!?!

    Das Problem ist das gleiche; Form1 ruft Form2 auf, von Form2 sollen Daten an Form1 (Hauptform) geschickt werden.
    Wenn ich die Sachen genau so eintipp, wie oben beschrieben, kommt bei

    private: Form1^ form1
    

    der Fehler:

    Es fehlt';' vor'^'

    .

    Blend ich die Zeile aus, ist alles gut. In Form2.h ist Form1.h includiert. Namespace ist der Gleiche, daran liegts auch nicht....... Oder hab ich heut Tomaten auf den Augen?
    Würd mich freuen, wenn mir jemand ein Tipp hätte, an was das noch liegen kann?!?!

    ----------
    Bzw. eine andere Frage wäre, ob man das auch mit Delegaten lösen könnte (damit ich eben die Instanz von Form1 mit angeben kann)?!?!
    Wenn ich mir allerdings in Form1 mit

    public: delegate void DelegatTyp(int^)
    

    einen erstelle, dann kann ich den in Form2 im Button_Click-Ereignis nicht so

    dlg = gcnew DelegatTyp(Haupt, &Form1::Anzahl)  // Haupt Instanz von Form1, Anzahl öffentliche Property von Form1
    

    erstellen, obwohl dort ja Form1 includiert ist?!?!



  • @Newtons Law:

    Am einfachsten ist:

    In Form1 eine Instanz von Form2 erzeugen und diese per ShowDialog starten...

    Form2^ F = gcnew Form2();
    Form2->ShowDialog();

    Anschliessend per DialogResult die Werte von Form2 an Form1 übergeben...
    oder properties nutzen.

    Das ganze ist dann allerdings modal und keine MDI Anwendung...



  • Dappeljuh schrieb:

    @Newtons Law:

    Am einfachsten ist:

    In Form1 eine Instanz von Form2 erzeugen und diese per ShowDialog starten...

    Form2^ F = gcnew Form2();
    Form2->ShowDialog();

    Anschliessend per DialogResult die Werte von Form2 an Form1 übergeben...
    oder properties nutzen.

    Das ganze ist dann allerdings modal und keine MDI Anwendung...

    Hmm, glaub ich denk zu kompliziert.... Aber mit dem DialogResult krieg ich doch nur ein Wert in die Form1 rüber, oder? (Sofern ich kein array oder so als Rückgabe verwende?)
    Mein Problem ist, dass ich aus einer Instanz von Form1 Form2 aufrufe, und aus der Form2-Instanz einige Werte an meine Form1-Instanz schieben will (hört sich kompliziert an, ist es aber hoffentlich nicht!). In der Instanz von Form2 ist meine Form1-Instanz leider nicht bekannt (das hab ich schon probiert), deswegen komm ich auch nicht an die Propertys von meiner Instanz Form1 ran....
    Muss glaub mal noch ein wenig überlegen, wie ich das am dümmsten lös...
    Aber das mit dem DialogResult merk ich mir mal! 😉
    Danke



  • Warum so komplex ?`

    Speicher die Ergebnisse in Form2 und lies diese nach dem ShowDialog aus Form2 auf. Somit muss sich Form2 nicht darum kümmern was mit den Werten geschehen soll.

    Form2 ^f2 = gcnew Form2(this);
    f2->ShowDialog();
    this->label1->Text = f2->ErgebnisFuerLabel1;
    


  • Wo ist denn hier der Smilie, der sich selbst eine Kopfnuss gibt?? 🙄

    HAb das die ganze Zeit in die andre Richtung probiert (also von Form2 aus), aber so ist es ja mal erste Sahne!

    Super Jungs, Danke!


Anmelden zum Antworten