none
C#, Daten zwischen 2 Forms austauschen RRS feed

  • Frage

  • Hallo zusammen,

    ich versuche Daten zwischen 2 Forms hin und her zu schieben.

    Das "hin" funktioniert auch, nur das zurück hakt ein wenig.

    Code Form1
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            public delegate void delPassData(TextBox text);
    
            private void button1_Click(object sender, EventArgs e)
            {
                double x = double.Parse(textBox1.Text);
                double y = double.Parse(textBox2.Text);
                double a = 2;
                double b = 3;
    
                double Wert = a*x + b*y;
                textBox3.Text = Wert.ToString("0.0");
    
                Form2 frm2 = new Form2();
                delPassData delpass = new delPassData(frm2.Data);
                delpass(this.textBox3);
                frm2.ShowDialog();
            }
    
            public void Data(TextBox TextForm2)
            {
                textBox4.Text = TextForm2.Text;
            }
        }
    }
    Code Form2
    
    namespace WindowsFormsApplication1
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }
    
            public delegate void delPassData(TextBox value);
    
            public void Data(TextBox txtForm1)
            {
                textBox1.Text = txtForm1.Text; 
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                double Wert = double.Parse(textBox2.Text);
                double ergebnis = Wert * 2;
                textBox3.Text = ergebnis.ToString("0.0");
    
                Form1 frm1 = new Form1();
                delPassData delpass = new delPassData(frm1.Data);
                delpass(this.textBox3);
                this.Close();
            }
        }
    }

    Wenn ich in Form 2 die Code Anweisung "this.close();" ausklammere zeigt er mir in Form2 in Textbox3 den Wert an.
    Er übergibt ihn aber nicht an Form1.... :(

    Wie kann ich die das "ergebnis" aus Form2 zurück in die Textbox4 aus Form1 laden ? Wo liegt mein Fehler ? :(

    Danke für eure Unterstützung.

    Viele Grüße

    Thorsten

    Sonntag, 10. August 2014 18:09

Antworten

  • Hallo,
    du erstellst in button1_Click eine neue Form. Diese ist nicht die selbe Instanz wie die eigentliche Form1.

    Du musst in Form2 ein Event implementieren, welches von Form1 abonniert wird:

    private void button1_Click(object sender, EventArgs e)
    {
      double Wert = double.Parse(textBox2.Text);
      double ergebnis = Wert * 2;
      textBox3.Text = ergebnis.ToString("0.0");
    
      var evt = this.MyEvent;
      if(evt != null)//Ist das Event abonniert?
        evt(this, new MyEventArgs(textBox3.Text));//Event auslösen und Daten übergeben
    }
    
    public EventHandler<MyEventArgs> MyEvent;
    
    public class MyEventArgs:EventArgs{
      //Eine Klasse zum transportieren von Daten mit Events
      public string Text{get;set;}
      public MyEventArgs(string text){
        this.Text = text;
      }
    }

    In Form1 kannst du nun das Event abonnieren und die Daten empfangen:

    private void button1_Click(object sender, EventArgs e)
    {
      double x = double.Parse(textBox1.Text);
      double y = double.Parse(textBox2.Text);
      double a = 2;
      double b = 3;
    
      double Wert = a*x + b*y;
      textBox3.Text = Wert.ToString("0.0");
    
      Form2 frm2 = new Form2();
      frm2.MyEvent += frm2_MyEvent;
      frm2.ShowDialog();
    }
    
    private void frm2_MyEvent(object sender, MyEventArgs e){
      //Event wurde ausgelöst
      this.TextBox3.Text = e.Text;//Eventdaten abrufen und in dieser Form ausgeben
    }

    Du scheinst schon versucht zu haben die Daten über Delegaten zu transportieren. Der Weg ist im Grunde auch nicht anders, als der hier gezeigte.

    Siehe auch: Ereignisse (C#-Programmierhandbuch)


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert Thorsten84 Sonntag, 10. August 2014 19:54
    Sonntag, 10. August 2014 19:06
  • Hallo,
    du hast einfach falsch mit den Delegaten jongliert.

    In Form2 brauchst du eine Eigenschaft oder Methode, die einen Delegaten entgegen nimmt und diesen dann abspeichert. So kannst du ihn später wieder aufrufen:

    public delegate void delPassData(TextBox value);
    
    public void SetDelegate(delPassData del)
    {
      this.del = del;//Methode abspeichern
    }
    
    private delPassData del;//ein Verweis auf den von außen gesetzten Delegaten
    
    private void button1_Click(object sender, EventArgs e)
    {
      double Wert = double.Parse(textBox2.Text);
      double ergebnis = Wert * 2;
      textBox3.Text = ergebnis.ToString("0.0");
    
      del(textBox3);//Die Methode aufrufen
    }
    Beim instanzieren von Form2 gibst du nun einfach deine Methode mit:
    Form2 frm2=new Form2();
    frm2.SetDel(MyDelMethod);
    frm2.Show();
    
    //...
    
    void MyDelMethod(TextBox3 tb){
      //tb ist die TextBox, die Form2 an del übergeben hat
    }
    Fürs Verständis: Ein Delegat ist die Deklarationsvorschirft für eine Methode. So wie eine Klasse für eine Variable. Du speicherst also einen Verweis auf eine andere Methode.


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert Thorsten84 Dienstag, 12. August 2014 08:00
    Montag, 11. August 2014 20:26

Alle Antworten

  • Hallo,
    du erstellst in button1_Click eine neue Form. Diese ist nicht die selbe Instanz wie die eigentliche Form1.

    Du musst in Form2 ein Event implementieren, welches von Form1 abonniert wird:

    private void button1_Click(object sender, EventArgs e)
    {
      double Wert = double.Parse(textBox2.Text);
      double ergebnis = Wert * 2;
      textBox3.Text = ergebnis.ToString("0.0");
    
      var evt = this.MyEvent;
      if(evt != null)//Ist das Event abonniert?
        evt(this, new MyEventArgs(textBox3.Text));//Event auslösen und Daten übergeben
    }
    
    public EventHandler<MyEventArgs> MyEvent;
    
    public class MyEventArgs:EventArgs{
      //Eine Klasse zum transportieren von Daten mit Events
      public string Text{get;set;}
      public MyEventArgs(string text){
        this.Text = text;
      }
    }

    In Form1 kannst du nun das Event abonnieren und die Daten empfangen:

    private void button1_Click(object sender, EventArgs e)
    {
      double x = double.Parse(textBox1.Text);
      double y = double.Parse(textBox2.Text);
      double a = 2;
      double b = 3;
    
      double Wert = a*x + b*y;
      textBox3.Text = Wert.ToString("0.0");
    
      Form2 frm2 = new Form2();
      frm2.MyEvent += frm2_MyEvent;
      frm2.ShowDialog();
    }
    
    private void frm2_MyEvent(object sender, MyEventArgs e){
      //Event wurde ausgelöst
      this.TextBox3.Text = e.Text;//Eventdaten abrufen und in dieser Form ausgeben
    }

    Du scheinst schon versucht zu haben die Daten über Delegaten zu transportieren. Der Weg ist im Grunde auch nicht anders, als der hier gezeigte.

    Siehe auch: Ereignisse (C#-Programmierhandbuch)


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert Thorsten84 Sonntag, 10. August 2014 19:54
    Sonntag, 10. August 2014 19:06
  • Hallo

    public static class FormManager { //Beide Fenster müssen IFormManagerWindow erben!!! private static IFormManagerWindow _window1; //Die erste Form private static IFormManagerWindow _window2; //Die zweite Form public static IFormManagerWindow Window1 { get { //Gibt das bereits geladene Fenster zurück, oder erstellt es, wenn es noch NULL ist. return (_window1 == null ? (_window1 = new MyFirstWindow()) : _window1); } } public static IFormManagerWindow Window2 { get { //Gibt das bereits geladene Fenster zurück, oder erstellt es, wenn es noch NULL ist. return (_window2 == null ? (_window1 = new MySecondWindow()) : _window2); } } } public interface IFormManagerWindow { ///return: Gibt an, ob die Daten angenommen wurden. Kann gerne Void sein. bool Send(object data); } /* Benutzung: - Fenster 1: IFormManagerWindow.Window1.Send("Daten..."); - Fenster 2: public bool Send(object data) { //Tu was du willst. } */

    Wie du siehtst, werden beide Fenster einfach von einem Assistenten verwaltet, die beiden Fenster bieten eine Funktion nach aussen an, die "Send" heißt.

    Umgekehrt funktioniert der Spaß natürlich auch, also von Fenster 2 zu Fenster 1.

    PS: Ich habe den Code frei Hand geschrieben, also wundere dich nicht, wenn irgendwo eine ";" o.ä. Fehlt.

    Visual Studio macht grade sein Update :)


    (C) 2014 Thomas Roskop

    Sonntag, 10. August 2014 19:15
  • Hallo Thomas,
    deine Lösung funktioniert zwar im Moment poblemlos, sobald eine Form aber mehrfach geöffnet wird funktioniert sie eben nicht mehr.

    Man sollte auf statische Felder/Eigenschaften verzichten, wenn die Daten nicht wirklich immer gleich sind. (Beispielsweise enthält die Environment-Kalsse viele statische Informationen bei denen das kein Problem ist.)

    Man solte es wirklich so handhaben, dass eine Form1 die Form2 kennt und Form2 nur über Events/Delegaten an Form1 senden kann.


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Sonntag, 10. August 2014 19:19
  • Danke für das Feedback.

    Dass es mehrere Formen geben könnte habe ich Garnicht bedacht, dachte es soll nur genau diese beiden zwei Formen geben. Bei mehren Fenster hast du natürlich Recht.


    (C) 2014 Thomas Roskop

    Sonntag, 10. August 2014 19:33
  • Hallo Tom,

    Danke für deinen schnellen Lösungsansatz.

    Nur für mein Verständnis ...kannst du mir eventuell erklären, warum es bei mir nicht mit dem Delegate funktioniert ?

    Montag, 11. August 2014 19:48
  • Hallo,
    du hast einfach falsch mit den Delegaten jongliert.

    In Form2 brauchst du eine Eigenschaft oder Methode, die einen Delegaten entgegen nimmt und diesen dann abspeichert. So kannst du ihn später wieder aufrufen:

    public delegate void delPassData(TextBox value);
    
    public void SetDelegate(delPassData del)
    {
      this.del = del;//Methode abspeichern
    }
    
    private delPassData del;//ein Verweis auf den von außen gesetzten Delegaten
    
    private void button1_Click(object sender, EventArgs e)
    {
      double Wert = double.Parse(textBox2.Text);
      double ergebnis = Wert * 2;
      textBox3.Text = ergebnis.ToString("0.0");
    
      del(textBox3);//Die Methode aufrufen
    }
    Beim instanzieren von Form2 gibst du nun einfach deine Methode mit:
    Form2 frm2=new Form2();
    frm2.SetDel(MyDelMethod);
    frm2.Show();
    
    //...
    
    void MyDelMethod(TextBox3 tb){
      //tb ist die TextBox, die Form2 an del übergeben hat
    }
    Fürs Verständis: Ein Delegat ist die Deklarationsvorschirft für eine Methode. So wie eine Klasse für eine Variable. Du speicherst also einen Verweis auf eine andere Methode.


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert Thorsten84 Dienstag, 12. August 2014 08:00
    Montag, 11. August 2014 20:26