Globales Verwenden von Variablen & TextBoxen u. ä.

Neflite

Grünschnabel
Hallo,

gibt es eine Möglichkeit Einstellungen oder Forms oder TextBoxen global bzw. von jedem Form aus anzusprechen?

Habe z.B. in einem Form den StreamReader mit der Variable sr verwendet und möchte nun diesen sr in einem anderen Form auch verwenden aber da meckert er natürlich das er hier noch nicht definiert wurde, genauso wie die textBoxInhalte des anderen Formulars die er einlesen sollte.

Weiss da wer Rat?

danke,

Neflite99
 
Hallo!

Standardmässig wird alles in einem Form als private deklariert. Eine Möglichkeit wäre die entsprechenden Objekte als public zu deklarieren. Wichtig dabei ist, dass die Deklaration nicht innerhalb einer Methode (wie z.B. Form_Load) steht, sondern außerhalb im Klassenbereich. Allerdings gilt diese Möglichkeit als ein bisschen "unsauber". Wie dem auch sei, Du kann anschließend auf alle public-deklarierten Objekte von außerhalb zugreifen, indem Du diese Schreibweise benutzt: Form1.PublicObject.

Wesentlich schöner wäre es, wenn Du entsprechende Getter/Setter deklarierst mit denen Du den Austausch vollziehst. Dazu musst Du wieder auf Klassenebene ein privates Objekt erstellen, welches Du dann im Getter/Setter zur Verfügung stellst.

Code in Form1:
Code:
public StreamWriter TheStream
{
   get { return sr; }
   set { sr = value; }
}
Im obigen Fall wäre das private-Objekt sr.

Du kannst auch nur einen Getter bzw. nur einen Setter machen, lass einfach get bzw. set weg, je nach dem welche Zugriffsrechte Du implementieren möchtest.

Hoffe ich konnte helfen ... :)
 
Zuletzt bearbeitet:
Hallo,

wow, danke für die schnelle Antwort aber da ich da noch nicht ganz mitkomme will
ich das Beispiel etwas konkretisieren.

Ich habe ein Form das heisst settingsForm.cs und beim starten dieses
Formulars läd er die Einstellungen einer Config.txt:

Hier der Code hierzu:
Code:
StreamReader sr = null;
try
{
	sr = new StreamReader("C:\\Config.txt"); 
	while (sr.Peek() >= 0) 
	{
		comboBoxServer.Text += sr.ReadLine(); 
		comboBoxDatabase.Text += sr.ReadLine();
		textBoxUserlogin.Text += sr.ReadLine();
		textBoxLoginpassword.Text += sr.ReadLine();
		textBoxAlso.Text += sr.ReadLine();
	}
}
catch (Exception ex)
{
	MessageBox.Show(string.Format("Fehler\n{0}", ex.Message));
}
finally
{
	if (sr != null)
		sr.Close();
}


Jetzt hätte ich aber gerne das er diese Einstellungen bereits läd wenn im Form loginForm auf den Button Anmelden klickt.
Daher habe ich versucht einfach den Code in das Form loginForm.cs zu kopieren
aber da meckert er es eben an.Ich glaube ich habe die Logik deines Getter/Setter Vorschlages kapiert aber die Praxis habert eben noch.hast du hier ein Code Beipspiel?
Wie gesagt das Laden der Einstellungen von der Txt soll er machen wenn der Anmeldebutton loginButton gedrückt wird.

Danke,

Neflite99

Bitte gepastete Code-Snippets in CODE-Tags angeben, danke. Mfg, Alex
 
Zuletzt bearbeitet von einem Moderator:
Sodala, jetzt hast Du mich verwirrt. *fg* ;)

Wieso machst Du es nicht einfach so, dass Du im Form loginForm.cs die Daten aus der Textdatei lädst? Das würde (so beim Überfliegen betrachtet *g*) klappen wie Du das gelöst hast, nur musst Du dort eben noch den StreamReader erstellen.
Oder gibts irgendeinen speziellen Grund wieso der StreamReader in settingsForm.cs sein muss?

Ich hätte da aber noch ein, zwei Tipps für Dich ... :)

1.) Du solltest keine Textdateien verwenden. Benutze lieber XML-Files. C#.NET besitzt diverse Klassen für diese Feature.

2.) Lagere alle Settings-Operationen (Methode etc.) in eine eigene Klasse aus. So kannst Du in jedem Formular einfach ein Objekt dieser Settings-Klasse erstellen und Du hast alle Methoden dort wo Du sie brauchst. Ist Geschmackssache, kann je nach Verwendungszweck sinnvoll bzw. weniger sinnvoll sein.

3.) Am schnellsten wäre es, wenn Du irgendwo die Konfiguration EINMAL lädst und dann immer an jede Klasse / Form / was auch immer übergibst.

Hoffe das passt alles zu Deinem Problem, hab bloß alles schnell überflogen. ;)
 
Entschuldige wenn ich dich verwirrt habe aber das war nicht meine Absicht! :rolleyes:


Ich seh schon ich muss die Geschichte von vorne aufrollen:

Also:

In der settingsForm.cs gibt es 3 TextBoxen und 2 DropdownFelder
In den 2 TextBoxen wird der Benutzername und das Passwort für den Login zum SQL-Server eingetragen. Und in der 3 Textbox wird der Pfad zu einer Access-Datenbank eingetragen.In den 2 DropDown Feldern kann man einen SQL-Servername auswählen und eine SQL-Datenbank. Weiterhin gibt es in diesem Formular einen "Einstellungen speichern" - Button der eben diese Einstellungen mit StreamWriter in besagter TXT- Datei speichert.

So, soviel zum settingsForm.cs!

Das loginForm.cs dient dazu sich anzumelden.Ist die Anmeldung erfolgreich, öffnet sich ein weiteres Formular namens artikelForm.cs. Dort gibt es den Button "Import" und "Einstellungen". Der Button Einstellungen öffnet oben erwähntes settingsForm.cs.

Der "Import" Button soll jedoch aufgrund der Einstellungen in der Txt. datei eine Datenbankverbindung zur Access-Datenbank aufbauen und diese Daten dann in die ebenfalls in der Txt-Datei eingetragen SQL-Datenbank kopieren, unter Verwendung der dort hinterlegten Verbindungseinstellungen!

Puh, ganz schön viel nicht wahr?

Ich hoffe du hast trotzdem noch "Lust" mir zu helfen! :)
CodeBeispiele wären auch nicht schlecht weil ich noch ein blutiger Anfänger bin!

Danke,

Neflite99
 
Zuletzt bearbeitet:
Also zu allererst meine Antwort könnte etwas Java Lastig sein, aber
da C# und Java sich sehr ähneln wirst du dies übertragen können:

Nutze Klassenmethoden, sprich static Methoden.

Code:
public class PrefsReader() {
  
   public static String[] read() {
      // auslesen und irgendwo speichern & zurueckgeben
      return data;
   }
}

..... formular 1

private void foo()  { 
    String[] prefs = PrefsReader.read();
}

formular 2
private void foo()  { 
    String[] prefs = PrefsReader.read();
}

Da statische Methoden der Klasse und nicht der Instanz der Klasse angehören, kann mann auf sie ohne eine entsprechende Instanz diese aufrufen.


Dennoch ist dieses Beispiel Schlecht da mann zwar ueberall wo die Einstellungen benoetigt werden nur eine Methode aufrufen muss, dennoch wird immer wieder diese Einstellungen gelesen. Darum bietet es sich an in der Applikationsinstanz diese Einstellungen einmal zu lesen und den einzelnen forms zur verfuegung zu stellen

Code:
class Application {

   public Application() {
        String[] prefs = new PrefsReader().read();
         formular1.setPrefs(prefs);
         formualr2.setPrefs(prefs);
   }

}
Vorteil ist:
Beide Formulare haben Referencen auf ein und die selben Einstellungen.

Dennoch würde ich auch dieses nicht tun. Java und wohl auch .net bietet einen die Möglichkeiten auf
spezielle Klassen zuzugreifen:

Code:
public class Test {

        public Test() throws IOException {
                Properties p = new Properties();
                p.load(getClass().getResourceAsStream("test.properties"));
                String name = p.getProperty("test.name");
                System.out.println(name);
        }

        public static void main(String[] args) {
                try {
                        Test test = new Test();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
}

Diese lesen vorgefertigte Properties fuer jede einzelne Klasse aus. Oder wenn mann es noch flexibler braucht:

Code:
/**
 * @author holyfly
 *
 * (c) by holyfly
 */
public class PrefMain {

        public PrefMain() throws BackingStoreException {
                Preferences prefs = Preferences.systemNodeForPackage(getClass());
                prefs.put("Test.System","geht");
                prefs.flush();
        }

        public void showPrefs() {
                Preferences prefs = Preferences.systemNodeForPackage(getClass());
                System.out.println(prefs.get("Test.System","default"));
        }

        public static void main(String[] args) {
                try {
                        PrefMain p = new PrefMain();
                        p.showPrefs();
                } catch (BackingStoreException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
}

Dies verhaelt sich so das es je nach Plattform entweder direkt in die Registrie oder in die Konfigurations ordner /etc/.java/ schreibt. Zudem gibts die möglichkeit zwischen Systemweite Einstellungen oder diesen User spezielle Einstellungen zu nutzen. Der Vorteil liegt auf der Hand, wenn bei deinem Programm der Windows User ay seine Datenbank verbindung dort ablegt, kann sie User gh nicht lesen und nutzen.
Textfiles bzw auch XML Files koennen dir diese einfachen und wertvollen Dienste so einfach nicht bieten. Drum schlag MSN auf und suche nach einer Preferences Klasse oder aehnliches.
 
So tschuldigung muss eben noch etwas an deinem Code rummotzen :) *nicht bös sein*

Code:
StreamReader sr = null;
try
{
	sr = new StreamReader("C:\\Config.txt"); 
	while (sr.Peek() >= 0) 
	{
		comboBoxServer.Text += sr.ReadLine(); 
		comboBoxDatabase.Text += sr.ReadLine();
		textBoxUserlogin.Text += sr.ReadLine();
		textBoxLoginpassword.Text += sr.ReadLine();
		textBoxAlso.Text += sr.ReadLine();
	}
}
catch (Exception ex)
{
	MessageBox.Show(string.Format("Fehler\n{0}", ex.Message));
}
finally
{
	if (sr != null)
		sr.Close();
}

ist schlecht, da du sämmtliche Exceptions abfängst. Fange nur diese Exceptions
ab die auch wirklich Auftreten könnten. Sprich hier währe es eine
IOException
siehe:
http://msdn.microsoft.com/library/d...f/html/frlrfsystemioioexceptionclasstopic.asp


Zusatz zu den Preferences:
Da ich sowieso auf msdn war habe ich eben etwas gesucht:
http://msdn.microsoft.com/library/d...crosoftwin32registryclasscurrentusertopic.asp

Damit kannst du deine Einstellungen in der Registry verwalten mit den Vorteilen die ich im vorhergehenden Post schon geschrieben habe.
 
Gibt es nicht die Möglichkeit das ich das Form wo der Aufruf des StreamReaders drin ist oben in einer neuen Klasse nochmal aufführe

So in etwa:

using System;
using System.IO;
using System.Windows.Forms;
using settingsForm;


Dummerweise meckert er mir auf diese Art an, das es keinen Typ oder Namespace dafür gibt.
Danke nochmal für die tollen Vorschläge. Christian Fein, aber mein Wissen reicht noch nicht so weit als das ich das richtig implementieren könnte.
Das Ding muss jetzt überhaupt erst mal laufen und dann kann ich das ja noch optimieren.
 
Also das Statement using ist lediglich dazu da, dass man sich Namespaces (Namensräume) in eine Klasse reinholt, das wird Dir bei Deinem Problem jetzt weniger hilfreich sein.

Aber Du kannst ein neues Objekt aus der Formklasse erstellen.
Code:
FrmMyForm myForm = new FrmMyForm();

Dann könntest Du über folgende Schreibweise auf die Methoden und Eigenschaften von FrmMyForm zugreifen, vorausgesetzt die betreffenden Methoden sind als public deklariert:
Code:
myForm.MeineMethode()
string x = myForm.MeineEigenschaft;
 
Zurück