BigBastis Blog

.NET Objekte zwischen Formularen verfuegbar machen

Introduction

user

Sebastian Gross

Sebastian Gross arbeitet in Bielefeld als Softwareentwickler für .NET und Java im Bereich Web.Als Fan der .NET-Plattform lässt er sich kein Userguppen Treffen und Community Event im Raum OWL entgehen.Dabei hat er eine besondere Vorliebe für das ASP.NET MVC Framework und für das Test Driven Development (TDD) entwickelt.


LATEST POSTS

Handling too long scrollspy menus 10th June, 2015

Java: Create ZIP archive 23rd March, 2015

.NET

.NET Objekte zwischen Formularen verfuegbar machen

Posted on .

Immer häufiger sehe ich in Foren die Frage, wie man Informationen (Objekte) zwischen Formularen zugänglich machen kann. Dies ist eigentlich kein großes Unterfangen, wenn man erstmal verstanden hat wie es funktioniert.

Die VB-Programmierer werden hier wohl schon das Wort „Global“ auf der Zunge liegen haben, aber wer diesen Artikel von mir gelesen hat, weis, dass ich das nicht gerne mag und deswegen euch hier andere Wege aufweisen werde.

Das Problem

Unser Problem ist, dass wir beispielsweise zwei Formulare haben, bei denen Form2 auf Informationen von Form1 zugreifen will. Da Objekte in .NET isoliert von einander laufen kann ein Objekt nicht einfach auf das andere zugreifen. Man muss diese Beiden Objekte mit einander bekannt machen bzw. diese mit einander verknüpfen.

Dieses Verknüpfen erreicht man mit Objektreferenzen. Dabei muss die Form die die andere Form aufruft eine Referenz auf das Objekt hinterlegen, dass dem anderen Formular bekannt sein soll und dieses an das fremde Form übergeben.

Die Lösung

Das beschriebene Vorhaben kann man auf verschiedenen Wegen erreichen, die sich aber relativ ähnlich sind. Ich möchte hier zwei recht ähnliche Methode zeigen, und eine die sich etwas unter scheidet.

Methode 1

Die Form die Informationen aus einer anderen Form benötigt erhält einen neuen Konstruktor der als Parameter die gewünschte Variable bekommt:

string wertAusForm1 = "";
public Form2(string info) {
    InitializeComponent(); //Wichtig!

    wertAusForm1 = info;
}
 

Hierbei ist „info“ die Variable die wir aus der Form1 übergeben bekommen, diese ist vom Typ String, aber natürlich könnt ihr diese nach eurem Bedarf anpassen. Und auch in der menge seid ihr nicht begrenzt, ihr könnt den Konstruktor um beliebig viele Parameter erweitern. Wichtig ist, dass die „InitializeComponent()“ Methode aufgerufen wird, falls ihr das Formular mit dem Visual Studio Designer gemacht habt, damit auch alle Komponenten initialisiert werden.

Aufruf aus Form1:

private void button1_Click(object sender, EventArgs e) {
    Form2 frm2 = new Form2(textBox1.Text);
    frm2.Show();
}
 

Der im Parameter übergebene Wert wird dann in der Klassen-variable „wertAusForm1“ gespeichert und ist nun für das ganze Formular verfügbar.

Diese Methode ist sehr simpel und schnell implementiert, doch wird es zum Problem, wenn man viele Variablen übergeben möchte, so schwellen die Konstruktoren schnell mal auf mehrere Zeilen an. An diesem Problem setzt methode 2 an.

Methode 2

Diese Methode unterscheidet sich kaum von der vorherigen, doch diesmal wollen wir viele Variablen übergeben, unseren Konstruktor aber nicht unnötig aufblasen. Hier bietet es sich an das ganze Formular als Parameter zu übergeben um auf alle Objekte des Formulars Zugriff zu erhalten. So haben wir nur einen Parameter aber Zugriff auf alle variablen.

Form3 Konstruktor:

//METHODE 2
public Form3(Form1 form) {
    InitializeComponent();

    aufrufendeForm = form;

    this.label2.Text = aufrufendeForm.textBox2.Text + " - " +
                aufrufendeForm.textBox3.Text + " - " +
                aufrufendeForm.textBox4.Text + " - " +
                aufrufendeForm.textBox5.Text + " - " +
                aufrufendeForm.textBox6.Text;
}
 

Aufrufcode in Form1:

private void button2_Click(object sender, EventArgs e) {
    Form3 frm3 = new Form3(this);
    frm3.Show();
}
 

Wie man sieht, übergibt man hier als Parameter „this“ sprich, sich selbst und in dem neuen Formular hat man dann bequem Zugriff auf alle TextBoxen von Form1. Bei dieser Methode muss man allerdings aufpassen dass die Objekte auf die man zugreifen will auch sichtbar, also public sind.

Dazu muss man den Form.Designer öffnen und ganz unten bei der Deklaration der Objekte die Sichtbarkeit auf Public ändern:

Bild1: Sichtbarkeitsänderung der Steuerelemente

Leider bringt auch diese Variante ein paar Unannehmlichkeiten mit sich, so muss die Klasse die die Informationen benötigt (hier Form3) genau wissen, von welcher Form diese aufgerufen werden kann und es im Konstruktor definieren. So kann man nicht ohne Aufwand Form3 aus einer weiteren Form aufrufen, da diese bereits Streng Typisiert auf Form1 eingestellt ist.

Methode 3

Die wohl sauberste Methode ist es wohl ein eigenes Objekt als Parameter zu übergeben. Dies hat den Vorteil, dass es für den ganzen Namensraum verfügbar ist und alle Klassen es definieren können und auch wieder verwenden können.

Dazu legen wir uns eine neue Klasse an in der wir Properties zu allen Informationen erstellen, die wir weiter geben möchten:

public class Informationen {

    public string info1 { get; set; }
    public string info2 { get; set; }
    public string info3 { get; set; }
    public string info4 { get; set; }
    public string info5 { get; set; }

}
 

Ich arbeite hier nur mit String Variablen, aber natürlich kann hier jeder beliebige Typ stehen. Vor dem Aufruf eines neuen Formulars können wir nun eine Instanz dieser Klasse bilden und mit unseren Werten befüllen um es anschließend als Parameter an die neue Form zu übergeben.

Form3 Konstruktor:

//METHODE 3
public Form3(Informationen infos) {
    InitializeComponent();

    this.infos = infos;

    this.label2.Text = infos.info1 + " - " +
                        infos.info2 + " - " +
                        infos.info3 + " - " +
                        infos.info4 + " - " +
                        infos.info5;
}
 

Und der Aufruf aus dem Aufrufer Formular (Form1):

private void button3_Click(object sender, EventArgs e) {
    Informationen infos = new Informationen();
    infos.info1 = textBox2.Text;
    infos.info2 = textBox3.Text;
    infos.info3 = textBox4.Text;
    infos.info4 = textBox5.Text;
    infos.info5 = textBox6.Text;

    Form3 frm3 = new Form3(infos);
    frm3.Show();
}
 

Auf diese Weise kann jedes beliebige Formular Informationen an Form3 übergeben ohne weitere Änderungen in Form3 vornehmen zu müssen. Die Klasse Informationen ist hier natürlich sehr leicht und schnell erweiterbar, sodass alle gewünschten Informationen schnell weiter gegeben werden können.

Alles wirklich nicht kompliziert, aber da ich es immer öfter antreffe dachte ich der Artikel könnt nützlich sein.

Hier habe ich noch das Demo Projekt zum Download:

Demoprojekt: Download [VS 2010]

profile

Sebastian Gross

http://www.bigbasti.com

Sebastian Gross arbeitet in Bielefeld als Softwareentwickler für .NET und Java im Bereich Web.Als Fan der .NET-Plattform lässt er sich kein Userguppen Treffen und Community Event im Raum OWL entgehen.Dabei hat er eine besondere Vorliebe für das ASP.NET MVC Framework und für das Test Driven Development (TDD) entwickelt.

Comments
user

Author bigbasti87

Posted at 09:13 13. September 2010.

Bloggd: .NET Objekte zwischen Formularen verfuegbar machen – http://blog.bigbasti.com/net-objekte-zwi

user

Author Thomas

Posted at 17:36 11. Februar 2011.

Hi, könntest du eventuell erklären, wie man auf die kompletten Komponenten einer Form aus einer Klasse heraus zugreifen kann?

Ich möchte Bspw. Aus der Klasse Connect.cs den Inhalt eines SQL Readers an eine Listbox aus Form 1 übergeben.
Wäre nett, wenn du was dazu schreiben könntest. Ansonsten wie immer : Super Infos bei dir!

user

Author admin

Posted at 22:39 11. Februar 2011.

Hallo Thomas,
du solltest dir vielleicht ein paar Gedanken zum Thema Softwareaufbau machen. Man sollte Klassen die auf Datenbanken zugreifen allgemein halten und nur auf ihre Aufgaben beschränken (Fachklassen) Von einer Klasse die Connect o.ä. heißt erwartet man nicht, dass diese irgendwelche Listen befüllt, du solltest hier eher andersherum vorgehen und Die Connect Klasse aus Form1 aufrufen und die nötigen Daten auslesen, dann hast du auch keine Zugriffsprobleme auf die Listbox da das Formular diese ja referenziert.
Wenn du auf Formelemente aus einer anderen Klasse zugreifen willst benötigst du eine Referenz auf diese Klasse und die Eigenschaften der Form auf die du zugreifen willst müssen öffentlich (public) sein siehe Methode 3 aus dem Artikel.
MfG, Basti

user

Author Thomas

Posted at 23:48 12. Februar 2011.

Hallo Basti,

danke für deine Antwort. So habe ich es jetzt gemacht.
Ziel war es für mich auf Grund der Angabe eines Nachnamens durch den User, eine Suche in der entsprechenden Datenbank auszulösen, die dann die entsprechenden Werte an meine Form übergibt.

In der Klasse [Datenbank]:
public static ArrayList searchDB(string Nachname)

..Datenbank Connect
.. Füllen der Daten mittels reader in eine ArrayList.
..Rückgabe an form

In der Form:
private void btnMIETER_Click(object sender, EventArgs e)
{
ArrayList ALMIETER = Datenbank.searchDB(rtbNachname.Text);

listBox1.Items.Clear();
foreach (Object objReader in ALMIETER)

usw.

Klappt hervorragend. Ich denke dass das die Lösung ist, die du meinst ( Zumindest vom Konzept her)

Bis dahin
Thomas

Kommentar verfassen

View Comments (4) ...
Navigation