Zugriff auf Variablen über die Form hinweg
-
ich habe eine frmMain (das ist Form1) mit einem Button, in der eine zweite Form (Form2) geöffnet wird. Dazu habe ich dem Projekt einfach eine neue Form hinzugefügt und dann im ClickEvent eines Buttons auf der Form1 flg eingefügt:
private void button1_Click(object sender, EventArgs e) { Form2 frm2 = new Form2(); frm2.ShowDialog(); }
Nun habe ich in der frmMain Variablen deklariert. Da ich diese in der Form2 brauche hab ich sie als public deklariert:
public partial class frmMain : Form { public SqlConnectionStringBuilder conStrB = null; public SqlConnection conn = null; public SqlCommand cmd = null; // ... }
Wie kann ich jetzt in Form2 auf die Variablen zugreifen?
-
Noch nie was von Kapselung gehört? Form2 hat die Variablen von Form1 schlichtweg nicht zu lesen.
Wenn Form2 Informationen brauch, dann übergib sie in einer Methode.
-
ok, hab zB flg GetMethodeGeschrieben:
public SqlConnection GetConnection() { return conn; }
Edit: eine Property könnt ich ja auch nehmen:
public SqlConnection connection { get { return conn; } set { conn = value; } }
Nun muss ich von der Form2 darauf zugreifen. In C++ musste man die header inkludieren von Form1. Wie macht man das in C#?
-
Andere Richtung, nicht die Form2 holt es sich, Form2 bekommt es von der Form1 noch vor dem ShowDialog übergeben.
Form2 frm2 = new Form2();
frm2.SetConnection(conn);
frm2.ShowDialog();
-
ich will doch aber in Form2 auf den Wert der Variable zugreifen bzw diesen ändern.
hab noch mal ein leeres Projekt erstellt mit einer einfachen Variablen x (als integer). Auf diese will ich in der Form2 zugreifen. Also deklarier ich in der Klasse Form 1 die Variable x als integer und initialisier sie mit 0. Nun möchte ich zB in Form 2 die Variable anzeigen.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private int x = 5; public int GetX() { return x; } public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form2 frm2 = new Form2(); frm2.ShowDialog(); } } }
Hab ich dann zB in Form2 ein label und schreib in den Konstruktor der Form2 "label1.Text = Form1." hatte ich erwartet, dass das IntelliSense die Methode GetX() mit auflistet. Dies is doch nun eine Methode der Klasse Form1. Warum taucht sie dann nicht auf? Der Namensraum ist doch der gleiche.
Edit: mir fällt grad auf, dass ich natürlich nur über das Objekt der Klasse auf die Methoden zugreifen kann. Also brauch ich den Objektnamen der Form1.
Habe dann einfach in Form2 ein Objekt von Form1 erzeugt und dann kann ich auch zugreifen:using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form2 : Form { public Form2() { InitializeComponent(); Form1 frm1 = new Form1(); label1.Text = frm1.GetX().ToString(); } } }
Ob man das so macht weiss ich nicht, aber es funktioniert. Obwohl ich mich frage wo eigentlich das Objekt der Form1 erzeugt wurde. Ich denke mal in Program.cs bei dem Aufruf:
Application.Run(new Form1());
Hätte man denn da nicht schreiben können:
Form1 frm1 = new Form1(); Application.Run(frm1);
?
-
Zu diesem Quälkot äußer ich mich einfach mal nicht.
-
rudpower, dir fehlen wirklich die elementarsten Grundlagen (der OOP)...
Frag dich mal, warum das Schlüsselwort 'new' so und nicht anders heißt -)
Hier mal ein FAQ-Eintrag zum Thema "Kommunikation von 2 Forms" aus einem anderen C#-Forum: http://www.mycsharp.de/wbb2/thread.php?threadid=5960
-
Falle es noch gebraucht werden sollte..
Du kannst nicht einfach eine neue Instanz der Form1 erstellen.
Die hat nichts mehr mit der ersten Instanz zu tun, welche die Form2 aufruft.Übergib der Form2-Klasse im Konstruktor das Form1 Element.
public Form2(Form1 MainForm) { label1.Text = MainForm.GetX().ToString(); }
Form2 rufst du folgendermassen auf:
private void button1_Click(object sender, EventArgs e) { Form2 frm2 = new Form2(this); frm2.ShowDialog(); }
grz
-
Formulare sollten sich GEGENSEITIG GAR NICHT kennen, sondern der Datenaustausch sollte über Eigenschaften/Methoden bzw. Ereignisse geschehen.
Dafür daß rudpower auch schon mit der Borland VCL gearbeitet hat, sollte eigentlich langsam das Verständnis für die Grundlagen der Forms-Programmierung da sein...
-
das weiss ich auch, dass man den Zugriff auf Variablen in anderen Forms über get/set-Methoden realisiert. Es ging nur darum, dass ich in diesem Fall mal auf Variablen über die Methoden in der anderen Form zugreifen wollte. Im Builder konnte man dazu einfach den Header der Form includen und dann einfach über das Formobjekt auf die öffentlichen Methoden zugreifen. Das wollte ich in C# auch machen.
-
Hallo rudpower,
In C# kann man (im Gegensatz zu C++) keine globalen Variablen verwenden (auch mit dem Borland C++ Builder sollte man niemals über die globalen Form-Variablen auf die anderen Formulare zugreifen, da man sich nicht sicher sein kann, ob diese richtig initialisiert sind).
Du wirst schon die gängigen OOP-Praktiken benutzen müssen...
-
alles klar.