Laden...

Wie kann ich eine Variable einer WinForm an eine andere Form übergeben?

Erstellt von Suspekta vor 3 Jahren Letzter Beitrag vor 3 Jahren 2.356 Views
S
Suspekta Themenstarter:in
19 Beiträge seit 2020
vor 3 Jahren
Wie kann ich eine Variable einer WinForm an eine andere Form übergeben?

Hallo Forum,

ich entschuldige mich schon mal für die wahrscheinlich blöde Frage aber ist es möglich eine WinForm als Variable an eine andere Klasse zu übertragen und auf diese dann zugreifen zu können.

Also ich habe eine Form mit Namen Hauptform und eine Klasse SL mit einer Methode SetztenText:
Diese Variante funktioniert. Aufruf aus Hauptform


SL.SetztenText(this);

Klasse SL


static class SL
{
public static void SetztenText(Hauptform formular)
        {
            formular.textbox1.text="Hallo";
        }
}

...............................................
Das funktioniert nicht ...


static class SL
{
public static void SetztenText(Form formular)
        {
            formular.textbox1.text="Hallo";
        }
}

er kennt in formular die Textbox nicht ...

Der Grund für die Klasse und der Methode ist, dass ich diese aus verschieden WinForms aufrufen möchte. Es gibt also nicht nur die "HauptForm", sonder auch Form2, Form2 etc.

Danke

16.834 Beiträge seit 2008
vor 3 Jahren

"Funktioniert nicht" ist keine Fehlermeldung, siehe [Hinweis] Wie poste ich richtig?
Hier ist es aber offensichtlich, dass es in einem Compiler-Error enden muss.

Aber ja, so funktioniert das einfach nicht, da Form einfach eine Klasse ist und nicht jede Form einfach Deine Textbox hat.
Das würde nur funktionieren, wenn Du die Ableitung (also Deine Klasse Hauptform, die von Form erbt) verwendest.
Weiterhin muss dazu die Textbox als öffentliche Eigenschaft hinterlegt sein, was sie wahrscheinlich nicht ist bzw. der Designer so standardmäßig nicht erstellt.

public class HauptForm : Form
{
   public TextBox TextBox1 {get; set;} // set vermutlich private, kenne Deine Anwendung nicht
}

Aus Architektursicht wäre es aber besser, wenn Du Dir daraus eine generische Umgebung schaffst, damit Du die TextBox nicht exposen musst.


public interface IMyDefaultForm
{
    void SetMaintext(string text);
}
public class HauptForm : Form, IMyDefaultForm
{
   private TextBox _textBox1; // vermutlich macht der Designer das so als default

   public void SetMaintext(string text) => _textBox1.Text = text;
}
public static void SetztenText<TForm>(TForm form) where TForm : IMyDefaultForm
        {
            form.SetMaintext("Hallo");
        }

Der Grund für die Klasse und der Methode ist, dass ich diese aus verschieden WinForms aufrufen möchte. Es gibt also nicht nur die "HauptForm", sonder auch Form2, Form2 etc.

Riecht so formuliert nach einer bösen Architekturverletzung.
Man übergibt eigentlich nicht bzw. nur in sehr wenigen Fällen ein UI-Objekt quer durch den Quellcode.

[Artikel] Drei-Schichten-Architektur

Erklär mal was Du wirklich vorhast, dann kann man Dir sagen, wie man es richtig macht.

4.939 Beiträge seit 2008
vor 3 Jahren

Hallo,

so funktioniert die objektorientierte Programmierung nicht.
Deine erste Methode liefert einen Fehler, weil textbox1 ein privater Member der Klasse Hauptform ist und deine zweite Methode kann generell nicht funktionieren, weil die Basisklasse Form keinen Member textbox1 enthält.

Du müßtest mit einer eigenen Form-Basisklasse oder einer Schnittstelle (interface) arbeiten, welche die Textzuweisung durchführt.

Lies dir auch mal in Ruhe die Artikel [FAQ] Kommunikation von 2 Forms bzw. meinen eigenen Artikel dazu Kommunikation von 2 Forms durch.

S
Suspekta Themenstarter:in
19 Beiträge seit 2020
vor 3 Jahren

Hi,

erstmal danke für deine Antwort.
Die Textbox steht auf "Modifieres Public"

Ich habe in einem Projekt 15 WinForm, alle haben eine Textbox1 und weitere Elemente.
Jetzt möchte ich nicht für jede WinForm eine eigene Methode in der SL Klasse erstellen

In VB kann man z.B. die WinForm als Object übergeben und darüber auf die WinForm zugreifen (Der Compiler nimmt das bei VB einfach hin) und rennt erst bei Laufzeit auf einen Fehler, wenn die Form das angesprochene Objekt nicht hat.

Was mir eingefallen ist, man könnte den Namen des WinForm als String an die Methode übertragen und dann mit einem IF Anweisung arbeiten. Finde ich aber umständlich

Also was:


static class SL
{
public static void SetzenText (String name)
{
if (name=="Hauptform") 
{
HauptForm.textbox1.text="sdfsd";
}

if (name=="Form2") 
{
Form2.textbox1.text="sdfsd";
}

}
}

16.834 Beiträge seit 2008
vor 3 Jahren

Ich habe in einem Projekt 15 WinForm, alle haben eine Textbox1 und weitere Elemente.
Jetzt möchte ich nicht für jede WinForm eine eigene Methode in der SL Klasse erstellen

Ja, dann hast Du einfach die Objekt-orientierte Programmierung noch nicht so ganz verstanden 😃

Hättest Dir einfach eine Basis-Klasse machen können, die die Textbox hat, und davon erben.

public abstract class MyBaseForm : Form ....
public class HauptForm : MyBaseForm ...

Der Compiler nimmt das bei VB einfach hin

Gut, dass wir mit C# ne ordentliche Sprache haben, die typisiert ist und sowas nicht einfach hinnimmt 😉
VB ist im Gegensatz zu VB.NET und C# auch eine non-object-basierte Sprache.

S
Suspekta Themenstarter:in
19 Beiträge seit 2020
vor 3 Jahren

Ja, dann hast Du einfach die Objekt-orientierte Programmierung noch nicht so ganz verstanden 😃

Ja das gebe ich zu ^^

Gut, dass wir mit C# ne ordentliche Sprache haben, die typisiert ist und sowas nicht einfach hinnimmt 😉
Hättest Dir einfach eine Basis-Klasse machen können, die die Textbox hat, und davon erben.

Darum versuche ich mir gerade C# beizubringen 😃

Vielleicht brauche ich doch mal einen Grundkurs ...

309 Beiträge seit 2020
vor 3 Jahren

Man könnte es ja auch z.B. so machen:


    public static class Form1ErweiterungMethod
    {
        public static void SetText(this Form1 form, string title)
            => form.Text = title;
    }

Würde da dagegen was sprechen, bzw. was wäre daran der Nachteil gegenüber einer Ableitung? @Abt, Th69,...

16.834 Beiträge seit 2008
vor 3 Jahren

Jim, das hat ja nichts mit der Textbox zutun, die sich auf der Form befindet.
Bringt ihm also nichts.

Daher entsprechend mein Beispiel mit der Methode über das Interface; alternativ direkt auf die Textbox einer Basis-Klasse.

4.939 Beiträge seit 2008
vor 3 Jahren

Ja, das würde mit dem Titel (Form.Text) funktionieren, aber eben nicht mit auf beliebigen Forms platzierten Elementen mit zufällig gleichen Namen (wie z.B. textbox1).
Darum ja der Hinweis auf eine Basisklasse (bzw. -interface).

Edit:
@Suspekta: Du solltest wirklich ein Grundlagenbuch zu C# und OOP durcharbeiten, z.B. das hier bei den "Ressourcen" verlinkte Open-Book Visual C# (2012) (Die Grundlagen gelten nach 8 Jahren immer noch 😉

309 Beiträge seit 2020
vor 3 Jahren

Achso sorry hatte seine Frage nicht verstanden

C
2.121 Beiträge seit 2010
vor 3 Jahren

Was mir eingefallen ist, man könnte den Namen des WinForm als String an die Methode übertragen

Das funktioniert solange bis du dein Form umbenennst. Dann findet der Vergleich der Namen nichts mehr und du suchst und suchst...

Noch ein offtpoic Hinweis zu deinem Methodennamen SetzenText.
Wenn du deutsche Bezeichner willst, verwende welche.
Wenn du englische Bezeichner willst, verwende welche.
Aber verwende doch keine deutsch klingenden nicht-deutschen Bezeichner 😉

5.299 Beiträge seit 2008
vor 3 Jahren

Du könntest eine Methode SetzenText(Textbox tb) schreiben.

static class SL
{
public static void SetztenText(Textbox tb)
        {
            tb.text="Hallo";
        }
}

Aufzurufen:

SL.SetztenText(this.texbox1);

Das würde von jedem Form aus gehen (ob sowas sinnvoll ist sei dahingestellt)

Der frühe Apfel fängt den Wurm.