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
"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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.
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";
}
}
}
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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 ...
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,...
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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 😉
Achso sorry hatte seine Frage nicht verstanden
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 😉
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.