Laden...

Kommunikation zwischen Forms mit statischer Variable?

Erstellt von Jesfreric vor 7 Jahren Letzter Beitrag vor 7 Jahren 3.102 Views
J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren
Kommunikation zwischen Forms mit statischer Variable?

Liebe Community

Ich habe eine typische Anfänger-Unverständnis-Frage wenn es um die Weitergabe von Variablen zwischen zwei Forms geht. Meine „Hauptform“ ist frmH und meine daraus aufgerufene Form „frmU“.
Ich habe einmal den Satz gehört, dass eine „Unterform“ (in diesem Fall frmU) nicht wissen darf/brauch , dass es seine Hauptform (frmH) überhaupt gibt. Das heißt ein Übergeben von Variablen in frmU mittels:
stVariable = frmH.stTest;
gilt als nicht sonderlich „edel“.

Ich habe deswegen das Übergeben von Variablen dann mittels eigener Methoden in frmU realisiert. D.h. ich hatte in frmU immer 2 Methoden

  1. public void setValues(String stA)
  2. public String getValues(Int iA)

Meine Code in der Hauptform (frmH) sah dann in etwa so aus:


….
frmU f1 = new frmU();
f1.setValues(stTest);				//hier hat frmU die notwendigen Werte bekommen
…


Und später


….
stTest = f1.getValues(1)		//Hier hat die frmH eine bestimmte Variable von frmU bekommen

Vor kurzem habe ich in einem Fachbuch allerdings einen Hinweis gelesen, dass eine Übergabe
wohl eher (wenn ich das richtig verstanden habe) via Übergabe der „Objektreferenz“ selber
geschieht.
Das heißt frmU wird so gestrickt:


//Code aus frmH

frmU f1 = new frmU(this);

…

Public partial class frmU : Form
{
   private frmH fRoot;
   public String stVariable;

   Public formU( frmH fTemp)
   {
     fRoot = fTemp
     stVariable = fTemp.stTest

   }
}


Soweit so gut.
Allerdings hätte ich dazu 2 Fragen:

  1. Welcher der zwei Wege ist der „bessere“?
  2. Warum bekomme ich eine Fehlermeldung wenn ich die Variable aus frmH mit „public static“ deklariere? Wenn ich das static weglasse, dann geht es. Static heißt doch eigentlich nur, dass sich eine Änderung der Variable auf alle Objekte (auch bestehende) dieser Klasse auswirkt. Das wäre ja das was ich möchte.

Viele Grüße
Jesfreric

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo Jesfreric,

hast du dir [FAQ] Kommunikation von 2 Forms mal durchgelesen?

Gruss

Coffeebean

3.003 Beiträge seit 2006
vor 7 Jahren
  1. Welcher der zwei Wege ist der „bessere“?

Der erste. Beim zweiten hat nicht nur FrmH eine Referenz auf FrmU, sondern auch noch umgekehrt, und beide können (theoretisch) fröhlich an den Eigenschaften des jeweils anderen herumfummeln. Noch enger koppeln geht kaum.

  1. Warum bekomme ich eine Fehlermeldung wenn ich die Variable aus frmH mit „public static“ deklariere? Wenn ich das static weglasse, dann geht es. Static heißt doch eigentlich nur, dass sich eine Änderung der Variable auf alle Objekte (auch bestehende) dieser Klasse auswirkt. Das wäre ja das was ich möchte.

Nein. static bei einem Klassenmember heisst, dass der Member auch aufgerufen werden kann, wenn es keine Instanz seiner Klasse gibt. static ist NICHT das, was du möchtest.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

Hallo

Habt vielen Dank für eure Nachrichten.
Dann werde ich mein Programm noch ein bisschen abändern.
Ich habe mir den "FAQ"-Abschnitt zu diesem Thema schon einmal zu Gemüte geführt, war mir aber danach noch etwas unsicher.
Wie beispielsweise verwende ich beim Schließen der frmU einen EventHandler?

Kann ich den "Schließen-Button" meiner frmU über einen EventHandler direkt mit der frmH verknüpfen, bzw. liefe das dann über "DialogResult"-Abfragen.

Zwecks static habe ich wohl etwas falsch verstanden. Stimmt es aber dann trotzdem, dass wenn ich eine static-Variable ändere, sie in allen Objekten automatisch geändert wird?
In dem Fachbuch steht:
"Sie (=Static Variable) steht innerhalb der Klasse allen Objekten gemeinsam zur Verfügung, sie wird also von den Objekten gemeinsam genutzt"...vorher steht noch, dass es die statische Eigenschaft pro Klasse nur einmal gibt, unabhängig der erzeugten Objekte.

Viele Grüße
Jesfreric

3.003 Beiträge seit 2006
vor 7 Jahren

Stimmt es aber dann trotzdem, dass wenn ich eine static-Variable ändere, sie in allen Objekten automatisch geändert wird?
In dem Fachbuch steht:
"Sie (=Static Variable) steht innerhalb der Klasse allen Objekten gemeinsam zur Verfügung, sie wird also von den Objekten gemeinsam genutzt"...vorher steht noch, dass es die statische Eigenschaft pro Klasse nur einmal gibt, unabhängig der erzeugten Objekte.

Es ist ein Unterschied, ob eine Variable nur einmal existiert, oder ob eine Variable überall den gleichen Wert hat.

Ersteres wird durch static erreicht, letzteres ist, was du verstanden hast 😉.

Und weil bei einem statischen Member alle und jeder von überall aus darauf Zugriff haben, kannst du zu keiner Zeit wissen, was drinstehen müsste. Deshalb - Finger weg.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

@ LaTino

Danke für deine Nachricht. Versprochen, ich lass die Finger davon, es geht nur rein ums Verständnis 😃

Würde ich jetzt also in einer Klasse Test einen public static Integer iA deklarieren und den Wert auf 0 setzen, dann gilt er für alle Objekte der Klasse Test, oder?
Sollte ich also später 5 weitere Objekte der Klasse Test deklarieren, wäre iA immer 0. Außer ich würde iA irgendwann auf z.b. 1 setzen, dann würde iA in allen vorhandenen/und zukünftigen Objekten auf 1 gesetzt oder?

Viele Grüße
Jesfreric

1.029 Beiträge seit 2010
vor 7 Jahren

Hi,

ja im Prinzip ist das so - nur dass deine Beschreibung immer noch den Kern der Aussage verfehlt 😉 iA wird dann genau einmal gesetzt - alle anderen Objekte greifen auf die selbe Variable zu.

LG

R
295 Beiträge seit 2008
vor 7 Jahren

Jein.
iA ist kein Teil eines Objekts.
Eine statische Variable ist eine sogenannte 'Klassenvariable'.
Variabeln eines Objektes, resp. einer Instanz einer Klasse nennt man dann 'Instanzvariable'.

Beispiel.

class Foo
{
    public Int32 MyInteger { get; set; }

    public static Int32 MyStaticInteger = 0;
}


class Program
{
    static void main(string[] args)
    {
        Foo myFoo = new Foo();
        myFoo.MyInteger = 2;                // Instanzvariable MyInteger wird für das Objekt 'myFoo' gesetzt.

        Foo mySecondFoo = new Foo();
        mySecondFoo.MyInteger = 3;          // Instanzvariable MyInteger wird für das Objekt 'mySecondFoo' gesetzt.

        Foo.MyStaticInteger = 4;            // Klassenvariable MyStaticInteger ist nicht Teil einer Foo-Instanz, sondern eine statische Variable.
    }
}

ServiceStack & Angular = =)

3.003 Beiträge seit 2006
vor 7 Jahren

Ergänzend: .NET kennt keine "globalen" Variablen, also welche, die man setzt und die man dann überall abrufen und verändern kann. Sieh 'static' als eine Art Ersatz für globale Variablen (trifft den Kern auch nicht ganz, aber für den Zweck hier reichts als Erklärung). Faustregel - wenn du nicht weisst, wie du eine Information von einer zur anderen Klasse kriegst, und auf die Idee kommst, dass man das prima mit einer globalen Variable (mit static) machen kann, dann ist diese Idee falsch 😉. (Es geht tatsächlich, und zwar so lange, bis es nicht mehr geht, und man nicht mehr sagen kann, wer jetzt den Wert der statischen Variable genau in dem Moment geändert hat, als du ihn abfragen wolltest. Und dann hat man den GAU schon.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

709 Beiträge seit 2008
vor 7 Jahren

.NET kennt keine "globalen" Variablen, also welche, die man setzt und die man dann überall abrufen und verändern kann.

Ich habe Public-Variablen in VB.NET-Modulen immer als eine Art globale Variable empfunden.

3.003 Beiträge seit 2006
vor 7 Jahren

Der Effekt ist - ähnlich wie bei static - derselbe, ja. Aber die Sprache an sich hat nunmal globale Variablen nicht vorgesehen. Mit gutem Grund.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

Ha, man mags kaum glauben, aber ich denke mir ist es nun klar was static bedeutet 😃
Der Punkt, dass Sie bei der Instanz einer Klasse nicht neu „gebildet“ wird, sondern sozusagen schon die ganze Zeit da ist, war für mich bis jetzt nicht klar.

Nochmals vielen Dank an alle die geantwortet haben. Solltet ihr noch Zeit haben würde ich mich freuen, wenn ihr mir noch bei der EventHandler-Frage helfen könntet 😃

5.299 Beiträge seit 2008
vor 7 Jahren

In deim Fall scheint ein Dialog vorzuliegen - das ist ein Spezialfall von SubForm, den man besser ohne Event implementiert.

Zeige die SubForm einfach mit .ShowDialog() an, dann ist das Hauptform so lange blockiert, bis das Subform schließt.
Und dann gehts genau da weiter, wo .ShowDialog() aufgerufen wurde.

Von der Kapselung her, und vonne Benutzer-Sicherheit das bestmögliche Design, und einfach ists obendrein.

In Vorüberlegung zur Form2Form-Kommunikation: Programm-Design überdenken , im "PasswordForm" ist das auch vorgeturnt zum Downloaden.

Der frühe Apfel fängt den Wurm.

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

Hi

Danke für deine Nachricht. Auf die Art und Weise habe ich es ursprünglich gemacht. Ich habe aber folgendes Problem damit...
Wenn ich auf den "Apply" oder "Cancel"-Button meiner frmU gehe, dann "Dispose()" ich die Form. Deswegen kann ich nach dem Verlassen von „ShowDiaglog()“ in meinem frmH-Code ja keine Werte mehr von frmU abfragen,...weil das Objekt ja nicht mehr existiert.
Wäre es dann besser, wenn ich den „Apply“ oder „Cancel“ Button nicht mit Dispose() sondern „Close()“ oder „Hide()“ bestücke? Dann könnte ich im frmH die Daten von frmU auslesen und danach im Skript das frmU mit f1.dispose() schließen.

Oder gibt es einen besseren Weg?

Viele Grüße
Jesfreric

3.003 Beiträge seit 2006
vor 7 Jahren

Dispose() ruft man nicht auf.[1]

LaTino

Edit: davon abgesehen ist ein Objekt nicht verschwunden, nur weil man Dispose() aufgerufen hat. Du gibst der Speicherverwaltung nur einen Hinweis, dass dieses Objekt möglicherweise bereinigt werden kann, sobald er das nächste mal aufräumt. Du hättest es also noch weiter verwenden können. (Ein Grund, wieso man Dispose() nicht aufruft. Die Garbage Collection von .NET weiss meistens besser als du, was weg kann 😉 )

[1] Ausnahmen bestätigen die Regel. Im Normalfall solltest du dich nicht um Zerstörung von Objekten und Speicherfreigabe kümmern, die Ausnahmen sind selten und recht speziell.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

Sehr schön:-)

Scheint gut zu klappen. Meine frmU Button haben jetzt das Commando "Close()" und definieren ein DialogResult als OK oder Cancel.

In meinem frmH wird dann das DialogResult abgefragt und die public deklarierten Variablen direkt vom Objekt f1 der Klasse frmU abgefragt.

Hab vielen Dank! 😃

Gruß
Jesfreric

3.003 Beiträge seit 2006
vor 7 Jahren

public deklarierten Variablen

Ich hoffe, das war ein Verschreiber, und du meinst Properties 😉.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

Oh Schreck
Ich befürchte schon, dass es eine "public deklarierte Variable" ist.

Bei Eigenschaften können (soweit ich das richtig verstanden habe) doch die set und get Methode überschrieben werden, was ich hierbei aber nicht mache(bzw. nicht als notwendig erachten würde.

Besagte Variablen/Eigenschaften sind Strings, die den Pfad eines FolderBrowserDiaglogs bzw. OpenFileDialogs speichern und später von frmH abgerufen werden sollen.

Viele Grüße
Jesfreric

3.003 Beiträge seit 2006
vor 7 Jahren

Benutze Auto-Properties. (Auch lesen: Is it bad practice to use public fields?)


public string MyProperty { get; set; } //wie eine öffentliche Variable, nur besser - s.o.
//oder...
public string MyProperty { get; private set; } //lesen jeder, schreiben nur icke.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

Hi

Danke für den Link. Jetzt mal eine blöde Frage. Warum empfiehlt sich hier die Verwendung einer Eigenschaft und nicht einer Variablen?
Bzw. sollte man sich grundsätzlich angewöhnen Eigenschaften zu verwenden, wenn Daten zwischen Klassen ausgetauscht werden sollen und Variablen dann eher nur intern Nutzen? Weil man könnte theoretisch ja eine Variable auch mit Referenz übergeben,...auch wenn dann etwaige Änderungen schlechter kontrolliert werden können...
Grüße
Jesfreric

5.299 Beiträge seit 2008
vor 7 Jahren

Der verlinkte Artikel argumentiert ebensogut auch für das Gegenteil: Manchmal machts überhaupt nix aus, auch mal ein public field zu verwenden.

Bestimmte Sachen kann man dann halt damit nicht machen.

Das schlimmste, was eim passieren kann, ist, dass mans später vlt. umändern muss in eine Property, wenn man die bestimmten Sachen dann doch braucht.
(Wobei manchmal aber sogar absehbar ist, dasses nie auftritt)

Ach noch ein schlimmeres gibts: Alle Programmierer hacken auf eim rum, wenn man sich untersteht, ein public field zu verwenden. 😉

Der frühe Apfel fängt den Wurm.

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

@ ErfinderDesRades

😃 😃 Ich finde konstruktive Kritik im Moment sehr sehr gut. Ich komme eigentlich aus einem ganz anderen Bereich, habe mich aber die letzten 2 Jahre (arbeitsbedingt) mehr und mehr mit Programmierung beschäftigt. Mittlerweile macht mir das so großen Spaß, dass ich gerne einen Quereinstieg in die Branche versuchen möchte. Leider fällt mir aber auf, dass mir einfach simple Grundlagen fehlen, die ich durch meine bisherigen Erfahrungen, bzw. durch die Bücher die ich lese nicht erarbeiten konnte. Ich habe mich eher zum Wald- und Wiesen Programmierer entwickelt, weswegen es gut tut, dass ich von "echten" Programmierern ein Feedback über meine Denkweisen und Arbeit bekomme....nur so komme ich weiter 😃

3.003 Beiträge seit 2006
vor 7 Jahren

Das beste Argument gegen public fields wird in dem verlinkten Artikel auch gebracht: API-Änderungen können wirklich, wirklich anstrengend werden, insbesondere, wenn Fremdbibliotheken auf die öffentlich deklarierten Variablen zugreifen.

Das Argument "es geht aber, also mach ich's, wird schon nichts passieren" greift nicht. Natürlich MUSS nicht etwas Schlimmes passieren. Wenn man aber anders vorgeht, KANN es gar nicht erst passieren. Und deshalb gilt ersteres als schlechter Stil. Wieso ein Risiko unnötig in Kauf nehmen? Damit man sich beim Tippen die zehn Zeichen "{get;set;}" spart? Nein, ist kein Argument.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

771 Beiträge seit 2009
vor 7 Jahren

Und wenn man gegen Interfaces programmiert, dann kann man sowieso nur Properties dort angeben und keine Fields: Why can't C# interfaces contain fields?
Also sollte man es auch bei Klassen gleich so abhandeln.

J
Jesfreric Themenstarter:in
40 Beiträge seit 2016
vor 7 Jahren

Alles klar 😃
Ich schreibs mir hinter die Ohren 😉

5.299 Beiträge seit 2008
vor 7 Jahren

Ja, ja, ja - es gibt viele Gründe für Properties, man kann damit mehr machen als mit fields, Apis, natürlich, Interfaces, Databinding und und und.

Aber es gibt auch Fälle, wo absehbar ist, dass man nichts davon braucht.

Und nu widerspreche ich mir selbst auch bisserl:

Mit Properties ist man wohl so gut wie immer auf der sog. "sicheren Seite".
public fields (ggfs readonly) sind gelegentlich eine Abkürzung für wenn man weiß, was man macht.

Mir ist halt immer wichtig, dass man quasi wach bleibt, und sich von patterns weder einschüchtern lässt, noch sich von ihnen das selber denken abnehmen lässt.

Ich "vermenschliche" Patterns iwie quasi als hohe Autoritäten, was die äussern hat großes Gewicht, und ich setze mich damit auseinander, um zu verstehen, was sie wollen.
Programmieren tu ich dann aber selber, und manchmal auch in Abweichung.

Hihi - habichs nicht gesagt?

Ach noch ein schlimmeres gibts: Alle Programmierer hacken auf eim rum, wenn man sich untersteht, ein public field zu verwenden.

Der frühe Apfel fängt den Wurm.