Autor Beitrag
Mathias1
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 05.05.09 15:32 
Hallo Leute,

ich habe ein Hauptprogramm Form1 mit einer eigenen Oberfläche. Nun möchte ich einen Dialog erstellen (Form2), der mittels eines Buttons auf Form1 aufgerufen wird. Diese Form2 soll auf alle Eigenschaften und Methoden der Form1 zugreifen können (über get/set).

Mein erster Versuch war, dass ich einfach von der Form1 erbe, also "public partial class Form2 : Form1". Danach kann ich problemlos auf alles zugreifen, jedoch habe ich dann das Problem, dass ich automatisch die grafische Oberfläche der Form1 mit übernehme. Das soll jedoch nicht sein. Es soll eine komplett neue Oberfläche für die Form2 erstellt werden.

Ich konnte bisher das Ganze umgehen, indem ich die Variablen, die ich in der Form2 benötigt habe, mittels eines eigenen Konstruktors mit übergeben habe. Aber es sind mittlerweile einfach zu viele Variablen und dazu kommt noch, dass die Methode einfach ineffizient und unprofessionell ist.

Gibt es für meinen Fall eine gute Lösung?

Vielen Dank im Voraus.
Greenberet
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 339
Erhaltene Danke: 20

Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
BeitragVerfasst: Di 05.05.09 16:29 
erstell doch einfach set/get in Form1 und übergib Form1 an Form2 via Konstruktor ( bzw. Form1 sollte ja Parent von Form2 sein... )
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 05.05.09 16:34 
user profile iconMathias1 hat folgendes geschrieben Zum zitierten Posting springen:
Aber es sind mittlerweile einfach zu viele Variablen und dazu kommt noch, dass die Methode einfach ineffizient und unprofessionell ist.
Dann ist es höchste Zeit, die Programmlogik von der Oberfläche zu trennen. Greenberets Vorschlag funktioniert natürlich auch, aber es wäre noch schöner, wenn du statt Form1 einfach dein Model als Konstruktor-Parameter übergibst.

_________________
>λ=
Mathias1 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 05.05.09 16:47 
@Kha:
Verstehe ich das richtig, dass du meinst ich solle eine neue Klasse erstellen, die meine ganzen Variablen und Methoden enthält. Diese übergebe ich dann den jeweiligen Form-Kontruktoren?

Es klingt schon logisch die Grafik vom Code zu trennen. Aber wenn ich das nun richtig verstehe, ist es fast identisch mit der Lösung von Greenberet. Er sagt genau das gleiche aus, mit dem Unterschied, dass er nicht die Oberfläche vom Code trennt.

Und dann noch eine Frage dazu:
Wenn ich dann die neu erstellten Klassen in eine jeweilige Form verwenden will, übergebe ich diese dann dem Kontruktor der Form. Erstelle ich dann in der Form eine neue "Variable" des Typs "Form" und weise der den übergebenen Wert zu? Also z.B.:

In Klasse mit dem Namen Klasse1.cs:
Form1 frm = new Form1(Klasse1);

Und in der Form1.cs:
Form frm;

public Form1(Form Frm)
{
InitializeComponent();
frm = Frm;
}

Wäre das die bzw. eine mögliche Lösung?

Es würden dann doch "intern" trotzdem alle Variablen im Arbeitsspeicher kopiert werden oder?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 05.05.09 21:01 
user profile iconMathias1 hat folgendes geschrieben Zum zitierten Posting springen:
@Kha:
Verstehe ich das richtig, dass du meinst ich solle eine neue Klasse erstellen, die meine ganzen Variablen und Methoden enthält. Diese übergebe ich dann den jeweiligen Form-Kontruktoren?
Das wäre ein Anfang, der wenigstens die gegenseitige Abhängigkeit der beiden Form-Klassen entfernen würde. Aber auf längere Sicht hin führt die Trennung zu klarerem und einfacherem Code, mit Patterns wie MVC erst recht.
Ein kleines Beispiel: Angenommen, du hältst in der Main-Form Daten in einer ListBox. Der Dialog muss dann mühsam aus dieser ListBox die Daten wieder auslesen. Viel eleganter wäre es doch, wenn beide Forms auf ein Model-Objekt zugreifen, das die Liste in einer "bekömmlicheren" Form enthält.

user profile iconMathias1 hat folgendes geschrieben Zum zitierten Posting springen:
Erstelle ich dann in der Form eine neue "Variable" des Typs "Form" und weise der den übergebenen Wert zu?
Warum vom Typ Form, das Objekt soll doch GUI-unabhängig sein?
Du erstellst in der Main-Form ein Objekt deiner MyModel-Klasse (wahrscheinlich ohne Vorfahr), füllst es und übergibst es dem Dialog-Konstruktor, der es wiederum in einem Klassenfeld vom Typ MyModel speichert.

user profile iconMathias1 hat folgendes geschrieben Zum zitierten Posting springen:
Es würden dann doch "intern" trotzdem alle Variablen im Arbeitsspeicher kopiert werden oder?
Wenn, dann werden nicht Variablen kopiert, sondern Werte/Objekte. Aber Klassen sind Referenztypen. Es wird lediglich eine Referenz übergebe, das Objekt bleibt dasselbe.

_________________
>λ=
Mathias1 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Do 07.05.09 09:22 
Danke, hab es nun so gemacht, dass ich alle Variablen und teilweise auch Methoden in eine externe Klasse ausgelagert hab. Die Haupt-Form erstellt eine Instanz dieser Klasse und gibt den einzelnen Dialog-Forms diese Klasse dem Konstruktor weiter.

Es funktioniert, danke!
C#Thomas
Hält's aus hier
Beiträge: 5

Windows 7
C# (VS 2009 Express)
BeitragVerfasst: Mo 18.05.09 18:30 
Hallo Zusammen,

bei dieser Thematik bin ich leider noch zu neu um das komplett verstanden zu haben.

Kannst Du mir eventuell ein Beispiel zeigen wie Du es erfolgreich lösen konntest? Ich leide
gerade an dem gleichen Problem. Ich benötige den Inhalt von ein paar TextBox'en die sich
in der Form 1 befinden und möchte diesen Inhalt in der Form 2 wieder zur Verfügung haben.

Gibts da 'ne "einfache" Lösung?

Grüßle
Thomas
Mathias1 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Mo 18.05.09 22:03 
Klar, ich versuche mal ein kurzes Beispiel zu machen:

Du hast zwei Klassen, einmal "Hauptklasse.cs" und "Unterklasse.cs".
Die Unterklasse besitzt selbstverständlich einen Standard-Kontruktor "public Unterklasse()". Du bastelst dir aber deinen eigenen Konstruktor. Zuvor erstellst du in der Unterklasse eine globale Variable vom Typ "Hauptklasse", z.B. "Hauptklasse var_hauptklasse". Danach erstellst du deinen eigenen Konstruktor "public Unterklasse(Hauptklasse parameter_hauptklasse)". In diesem weist du deiner globalen Variable "var_hauptklasse" deine Hauptklasse zu. Das wars. Nun kannst du auf alle freigegebenen Variablen deiner Hauptklasse zugreifen (beachte, dass diese entweder "public" sein müssen oder du die Eigenschaft "get/set" für die jeweilige Variable gesetzt haben musst).

Beispiel:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
//Auszug Hauptklasse
public partial class Hauptklasse : Form
{
  public string ich_bin_eine_variable;

  public Hauptklasse() //Standardkonstruktor
  {
    Initialize Component();
  }

  public button1_click(object sender, EventArgs e)
  {
    ich_bin_eine_variable = textbox1.text;
  }

...
}

//Auszug Unterklasse
public class Unterklasse
{
  private Hauptklasse var_Hauptklasse;
  private string variable_Unterklasse;

  public Unterklasse(Hauptklasse parameter_Hauptklasse) //dein eigener erweiterter Kontruktor
  {
    var_Hauptklasse = parameter_Hauptklasse;
  }

  public void ich_bin_eine_methode()
  {
    variable_Unterklasse = var_Hauptklasse.ich_bin_eine_variable;
  }
}

In meinem Beispiel beinhaltet die Unterklasse keine Form. Falls das bei dir der Fall ist, dann wird deine Klasse von "Form" erben, also lautet die Zeile oben "public class Unterklasse : Form" und dein eigener Kontruktor muss die Zeile "Initialize Component();" beeinhalten, damit die Form initialisiert werden kann.

Mein Beispiel ist zwar nicht sehr einfallsreich, aber ich hoffe das Prinzip ist klar geworden. Falls noch Fragen offen sind, dann melde dich nochmal.

Moderiert von user profile iconKha: C#-Tags hinzugefügt