Benutzer mit den meisten Antworten
Globale Variable benötigt

Frage
-
Hi guys,
stehe irgendwie uff'm Schlauch.
Ganz allgemein gefragt: Wie deklariere ich eine Stringvariable, damit diese in allen Formularen meines Projektes zur Verfügung steht. Baue nämlich in mindestens 2 Formularen eine ACCESSverbindung auf und benötige die zuvor von einem Benutzer in einem Objekt der Klasse OpenFileDialog hinterlegten Datenbankdaten in beiden Formularen...
string connection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + ofd.FileName;
soll in beiden Formularen verfügbar sein,aber natürlich nur einmal deklariert werden
- Bearbeitet tklustig Donnerstag, 13. April 2017 13:13
Antworten
-
Hallo,
du wirst um ein Singleton oder statische Instanz nicht herum kommen, siehe Toms Antwort.
Eine rohe Fassung, die einen OleConnectionStringBuilder einsetzt und einige Basisprüfungen macht:
using System; using System.Data.OleDb; using System.IO; namespace ElmarBoye.Samples.Code { public class AccessConnection { private static AccessConnection _instance = new AccessConnection(); public static AccessConnection Default { get { return _instance; } } private AccessConnection() { // Optional Vorgabe aus den Settigs (User) string defaultFileName = Properties.Settings.Default.AccessFileName; if (!String.IsNullOrWhiteSpace(defaultFileName) && File.Exists(defaultFileName)) { BuildConnectionString(defaultFileName); } } private string _fileName; // wenn durchgängig via Settings ist die Variable nicht notwendig public string FileName { get { return this._fileName; } set { BuildConnectionString(value); _fileName = value; Properties.Settings.Default.AccessFileName = _fileName; } } private string _connectionString; public string ConnectionString { get { if (String.IsNullOrWhiteSpace(_connectionString)) { throw new ArgumentNullException("ConnectionString", "Der Dateiname für die Verbindungszeichenfolge wurde nicht initialisiert."); } return this._connectionString; } } public OleDbConnection Connection { get { return new OleDbConnection(this.ConnectionString); } } private void BuildConnectionString(string fileName) { if (String.IsNullOrWhiteSpace(fileName)) { throw new ArgumentNullException("FileName"); } if (!File.Exists(fileName)) { throw new IOException($"Access Datei '{fileName}' existiert nicht."); } var builder = new OleDbConnectionStringBuilder(); builder.Provider = "Microsoft.Jet.OLEDB.4.0"; builder.PersistSecurityInfo = false; builder.OleDbServices = -4; builder.DataSource = fileName; this._connectionString = builder.ToString(); } } }
Optional: In einem User Setting wird der verwendete Dateiname für eine spätere Verwendung gespeichert. Denkbar wäre ebenso, den Dateidialog für die Auswahl einzubinden.
Verwendbar in etwa so:
AccessConnection.Default.FileName = @"C:\TEMP\A00.mdb"; string connectionString = Code.AccessConnection.Default.ConnectionString; var connection = AccessConnection.Default.Connection;
Gruß Elmar
- Als Antwort vorgeschlagen Stefan FalzModerator Donnerstag, 13. April 2017 21:20
- Als Antwort markiert Stefan FalzModerator Freitag, 14. April 2017 07:43
Alle Antworten
-
Hallo,
deklariere die Variable global
string connection = "";
Nach dem OpenFileDialog setze
connection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + ofd.FileName;
Wenn du connection nutzt, prüfe auf Länge 0, und fange den Fehler ab. Es muss dann zuerst der OpenFileDialog gemacht sein, bevor man connection benutzen kann.
Gruß Guido
- Bearbeitet Guido Franzke Donnerstag, 13. April 2017 13:20 Formatierung
-
Aber das bringt doch nix.
In dem Moment, wo ich mittels
Form1 fm = new Form1(); fm.Show();
ein neues Formular erzeuge, kann ich da nicht mehr auf connection zugreifen,da es nicht bekannt ist.
Ein weiteres OpenFileDialog will ich doch vermeiden...
- Bearbeitet tklustig Donnerstag, 13. April 2017 13:51
-
Zum Beispiel so:
public class Test1 { public Test1() { Global.connection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + ofd.FileName; } } public class Test2 { public Test2() { string con = Global.connection; } } public static class Global { public static string connection = ""; }
Allerdings bin ich kein Freund davon, wegen Thread-Sicherheit usw.
Eine elegantere Lösung wäre ein Singleton.
Gruß
Stefan
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
-
Hallo zusammen,
um das klar zu stellen: In C# gibt es keine globalen Variablen.
Das beste dürfte eine Statische Eigenschaft sein, wie von Stefan gezeigt, diese enthält stets das selbe - egal von wo aus man drauf zugreift. (BTW, etwas anders sieht es mit ThreadStatic aus.)
Was Singleton vs Static betrifft: Link 1, Link 2, Link 3, ...
Wenn du komplexere Einstellungen geplant hast empfehle ich dir die Verwendung eines Singleton, das kann Dinge wie die Serialisierung oder das Zurücksetzen vereinfachen.Thread sicher ist erstmal keine der beiden Lösungen. Da muss stets Vorsicht geboten sein.
An deiner Stelle würde ich eine eigene Settings-Klasse implementieren, welche die Einstellungen verwaltet. So könntest du die getroffene Verbindung auch einfach fürs nächste mal speichern. Verwenden kannst du natürlich auch Anwendungseinstellungen, damit könntest du das selbst implementieren irgendwelcher statischer Dinge komplett weg lassen.
Viele Grüße, Tom Lambert - MVP, MCC und MSP
Wozu Antworten markieren und Posts bewerten? Klicke hier
Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub -
Hallo,
du wirst um ein Singleton oder statische Instanz nicht herum kommen, siehe Toms Antwort.
Eine rohe Fassung, die einen OleConnectionStringBuilder einsetzt und einige Basisprüfungen macht:
using System; using System.Data.OleDb; using System.IO; namespace ElmarBoye.Samples.Code { public class AccessConnection { private static AccessConnection _instance = new AccessConnection(); public static AccessConnection Default { get { return _instance; } } private AccessConnection() { // Optional Vorgabe aus den Settigs (User) string defaultFileName = Properties.Settings.Default.AccessFileName; if (!String.IsNullOrWhiteSpace(defaultFileName) && File.Exists(defaultFileName)) { BuildConnectionString(defaultFileName); } } private string _fileName; // wenn durchgängig via Settings ist die Variable nicht notwendig public string FileName { get { return this._fileName; } set { BuildConnectionString(value); _fileName = value; Properties.Settings.Default.AccessFileName = _fileName; } } private string _connectionString; public string ConnectionString { get { if (String.IsNullOrWhiteSpace(_connectionString)) { throw new ArgumentNullException("ConnectionString", "Der Dateiname für die Verbindungszeichenfolge wurde nicht initialisiert."); } return this._connectionString; } } public OleDbConnection Connection { get { return new OleDbConnection(this.ConnectionString); } } private void BuildConnectionString(string fileName) { if (String.IsNullOrWhiteSpace(fileName)) { throw new ArgumentNullException("FileName"); } if (!File.Exists(fileName)) { throw new IOException($"Access Datei '{fileName}' existiert nicht."); } var builder = new OleDbConnectionStringBuilder(); builder.Provider = "Microsoft.Jet.OLEDB.4.0"; builder.PersistSecurityInfo = false; builder.OleDbServices = -4; builder.DataSource = fileName; this._connectionString = builder.ToString(); } } }
Optional: In einem User Setting wird der verwendete Dateiname für eine spätere Verwendung gespeichert. Denkbar wäre ebenso, den Dateidialog für die Auswahl einzubinden.
Verwendbar in etwa so:
AccessConnection.Default.FileName = @"C:\TEMP\A00.mdb"; string connectionString = Code.AccessConnection.Default.ConnectionString; var connection = AccessConnection.Default.Connection;
Gruß Elmar
- Als Antwort vorgeschlagen Stefan FalzModerator Donnerstag, 13. April 2017 21:20
- Als Antwort markiert Stefan FalzModerator Freitag, 14. April 2017 07:43
-
Dann werde ich wohl die Klasse von Elmar verwenden.
Wie immer: Vielen Dank für die zahlreichen Posts!!
- Als Antwort markiert tklustig Donnerstag, 13. April 2017 21:19
- Tag als Antwort aufgehoben Stefan FalzModerator Donnerstag, 13. April 2017 21:20
- Als Antwort markiert tklustig Freitag, 14. April 2017 07:25
- Tag als Antwort aufgehoben Stefan FalzModerator Freitag, 14. April 2017 07:43
-
Hi,
aus verschiedensten Gründen würde ich dich erneut bitten, die "Als Antwort markieren" Funktion so einzusetzen, wie sie gedacht ist, nämlich, um das oder die Posting(s) zu markieren, das oder die die Antwort(en)/Lösungen für deine Frage(n) beinhalten.
Es macht für niemanden Sinn, dein eigenes Abschlussposting als Lösung zu markieren, wenn dort keinerlei Lösung enthalten ist.
Da Du dich hier für Elmars Lösungsvorschlag entschieden hast, wäre es daher am hilfreichsten (auch für andere User, die irgendwann mal über diesen Thread stolpern weil Sie das gleiche oder ein sehr ähnliches Problem haben), sein Posting als Antwort zu markieren. Ich habe das in diesem Fall jetzt so gemacht.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community