Verwenden von "My.Settings" in Visual Basic 2005

Veröffentlicht: 19. Jan 2005

Von Emad Ibrahim

In diesem Artikel wird erläutert, wie Visual Basic 2005 durch die My.Settings-Klasse das Speichern von Anwendungs- und Benutzereinstellungen in Visual Basic 2005 erheblich vereinfacht (11 gedruckte Seiten).

Hinweis Dieser Artikel und die Codebeispiele basieren auf einer Vorabversion von Microsoft Visual Studio 2005, die früher den Codenamen "Whidbey" hatte. Änderungen an allen in diesem Artikel enthaltenen Informationen sind vorbehalten.

Auf dieser Seite

 Einführung
 Herkömmliche Vorgehensweise
 Neue und bessere Vorgehensweise
 Erweiterte Einstellungen
 Schlussbemerkung

Einführung

Windows Forms-Anwendungen nutzen Daten, die zum Ausführen der Anwendung erforderlich sind. In den meisten Fällen ist es nicht sinnvoll, diese Daten direkt in den Code aufzunehmen, da andernfalls die Anwendung jedes Mal neu kompiliert werden müsste, wenn Sie eine Änderung an den Daten vornehmen. Wenn Ihre Anwendung einen Webdienst oder eine Datenbank verwendet, möchten Sie die URL oder die Verbindungszeichenfolge möglicherweise in einer separaten Datei speichern, damit Sie diese Daten jederzeit problemlos ändern können. Wenn in Ihrer Anwendung das Fensterlayout sowie andere Anpassungen der Benutzeroberfläche gespeichert werden, möchten Sie diese Informationen sicherlich für jeden Benutzer gesondert speichern.

Früher wurden diese Daten an vielen verschiedenen Speicherorten abgelegt, beispielsweise in INI-Dateien, in der Registrierung oder in CONFIG-Dateien. In Microsoft .NET Framework 1.0 wurde das Konzept von app.config-Dateien eingeführt. Hierbei handelt es sich um XML-Dateien, in denen die erwähnten Einstellungen gespeichert werden. Jedes der genannten Verfahren birgt jedoch einige Probleme in sich:

  • Einstellungen sind nicht typsicher.

  • Ein beträchtlicher Codierungsaufwand ist erforderlich (beispielsweise zum Lesen und Schreiben von Dateien).

  • Beim Speichern der Einstellungen in der Registrierung muss Ihre Anwendung über ausreichende Sicherheitsberechtigungen für den Zugriff auf die Registrierung verfügen.

  • Benutzerbereichseinstellungen für die Anwendungen sind nur schwer zu verwalten.

Die neue Architektur für Anwendungseinstellungen berücksichtigt diese Anforderungen, da sie ermöglicht, Anwendungsbereichs- und Benutzerbereichs-Einstellungen auf einfache Weise auf dem Client zu speichern. In Visual Studio oder mit einem Code-Editor können Sie eine Einstellung für eine bestimmte Eigenschaft definieren, indem Sie den Namen, den Datentyp, den Standardwert und den Bereich (Anwendung oder Benutzer) dieser Eigenschaft angeben.

Die Funktionsweise von Anwendungseinstellungen beruht darauf, dass Daten jeweils im XML-Format in verschiedenen CONFIG-Konfigurationsdateien gespeichert werden, je nachdem, ob die Einstellung den Anwendungs- oder den Benutzerbereich betrifft. Anwendungsbereichseinstellungen sind schreibgeschützt. Da es sich bei Anwendungsbereichseinstellungen um Programminformationen handelt, müssen Sie diese in der Regel auch nicht überschreiben. Benutzerbereichseinstellungen hingegen können zur Laufzeit gefahrlos gelesen und geschrieben werden, selbst wenn Ihre Anwendung in einer Umgebung mit eingeschränkter Vertrauenswürdigkeit ausgeführt wird.

 

Herkömmliche Vorgehensweise

Im .NET Framework 1.0 wurde mit der Datei app.config das Konzept der CONFIG-Dateien eingeführt. Die Anwendung speichert in dieser Datei zahlreiche Anwendungseinstellungen, die speziell für Ihre Anwendung gültig sind. Bei dieser Datei handelt es sich um eine einfache XML-Datei, die mit dem Editor problemlos bearbeitet werden kann, wenn Sie Anwendungseinstellungen ändern oder neue hinzufügen möchten. Beispielsweise eignet sich diese Datei hervorragend als Speicherort für die Adresse des SMTP-Servers, eine Datenbankverbindungszeichenfolge oder ähnliche Daten. Durch die .NET Framework 1.0-Implementierung ergaben sich jedoch einige Nachteile. Ein Nachteil war das Fehlen eines einfachen Verfahrens zum Zurückschreiben von Daten in die Datei. Wenn Sie Einstellungen auf einer Seite oder in einem Formular in Ihrer Anwendung ändern wollten, mussten Sie die Datei als XML-Datei laden, die gewünschten Änderungen vornehmen und die Datei dann wieder in den Speicher schreiben. Ein weiterer Nachteil bestand darin, dass der Zugriff auf Eigenschaften in der CONFIG-Datei nicht typsicher war. Die folgende Codezeile kann beispielsweise zwar problemlos kompiliert werden, könnte jedoch auch einen Laufzeitfehler auslösen, wenn die Einstellung PageSize keine Ganzzahl ist (keine Typsicherheit):

Dim PageSize As Integer = 
Configuration.ConfigurationSettings.AppSettings("PageSize")

Ein Benutzer oder Entwickler könnte ungehindert folgenden nicht numerischen Wert in diese Anwendungseinstellung eingeben und damit zur Laufzeit einen Fehler auslösen.

<add key="PageSize" value="ten"/>

 

Neue und bessere Vorgehensweise

Mit dem .NET Framework 2.0 werden die genannten Nachteile und andere Unzulänglichkeiten größtenteils behoben. Zunächst werden Sie feststellen, dass Sie neue Einstellungen jetzt noch einfacher als bisher erstellen können. Sie müssen dazu nicht einmal die CONFIG-Datei öffnen und die gewünschte neue Einstellung eingeben. Stattdessen müssen Sie lediglich den Einstellungs-Designer auf dem Formular für die Projekteigenschaften öffnen und die neuen Einstellungen hinzufügen. Dann können Sie den Namen, den Typ und den Bereich (Anwendung oder Benutzer) für jede Einstellung auswählen.

Bereich

Einstellungen für den Anwendungsbereich sind schreibgeschützt und werden von allen Benutzern der betreffenden Anwendung gemeinsam genutzt. Diese Einstellungen werden in der Datei app.config im Abschnitt <applicationSettings> gespeichert.

Hinweis Dieser Abschnitt ist nicht mit dem im vorhergehenden Text erwähnten Abschnitt <appSettings> identisch, der in .NET 1.0 verwendet wird.

Zur Laufzeit befindet sich die Datei app.config im bin-Ordner und wird nach dem Namen Ihrer Anwendung benannt (MySettingsDemo.exe.config). Als Anwendungsbereichseinstellung gilt beispielsweise eine Datenbankverbindungszeichenfolge, die URL eines Webdienstes, die IP-Adresse eines Servers oder ähnliche Daten.

<applicationSettings>
    <MySettingsDemo.MySettings>
      <setting name="SMTPServerIP" serializeAs="String">
        <value>127.0.0.1</value>
      </setting>
      <setting name="MyServicesURL" serializeAs="String">
        <value>https://localhost/myservices.asmx</value>
      </setting>
    </MySettingsDemo.MySettings>
  </applicationSettings>

Benutzerbereichseinstellungen sind für jeden einzelnen Benutzer spezifisch. Diese Einstellungen können durch den Anwendungscode zur Laufzeit auf sichere Weise gelesen und festgelegt werden. Benutzerbereichseinstellungen werden in der Datei user.config gespeichert. Vom technischen Standpunkt aus betrachtet sind je Anwendung eigentlich zwei user.config-Dateien vorhanden: eine Datei für Nicht-Roaming und eine Datei für Roaming. Obwohl in der Dokumentation der Betaversion von Visual Basic 2005 angegeben ist, dass der Datei user.config der Name des Benutzers zugewiesen wird (joe.config), trifft dies nicht zu. Die Datei user.config wird in folgendem Pfad erstellt: <c:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\<appdomainname>_<eid>_<hash>\<version>. Dabei gilt Folgendes:

  • <c:\Documents and Settings> ist das Benutzerdatenverzeichnis entweder für Nicht-Roaming (Local Settings) oder Roaming.

  • <username> ist der Benutzername.

  • <companyname> ist, sofern verfügbar, der Wert von CompanyNameAttribute. Andernfalls können Sie dieses Element ignorieren.

  • <appdomainname> ist der Wert von AppDomain.CurrentDomain.FriendlyName. Hierfür wird als Standardwert normalerweise der Name der ausführbaren Datei übernommen.

  • <eid> ist der URL, StrongName oder Pfad auf Grundlage der Daten, die für das Hashing verfügbar sind.

  • <hash> ist ein SHA1-Hash der Daten, die von CurrentDomain erfasst wurden. Hierbei wird folgende Reihenfolge bevorzugt:

    1. StrongName

    2. URL

      Wenn keiner dieser beiden Datenwerte verfügbar ist, verwenden Sie den Pfad der EXE-Datei.

  • <version> ist die Einstellung AssemblyVersionAttribute von AssemblyInfo.

Ein Beispielpfad sieht wie folgt aus:

C:\Documents and Settings\Emad.BROKENOAK\Local Settings\Application 
Data\MySettingsDemo\MySettingsDemo_9cfe5ef1\1.0.0.0

Beim Öffnen des Beispielpfads ergibt sich eine ähnliche Verzeichnisstruktur wie in Abbildung 1.

Beispielpfad
Abbildung 1: Beispielpfad

Hinweis Der Speicherort der hier dargestellten und beschriebenen Einstellungskonfigurationsdatei gilt für die Betaversion 1. Für die Endversion von Visual Basic 2005 ist der entsprechende Speicherort jedoch noch nicht endgültig festgelegt.

Die Datei user.config wird zur Laufzeit automatisch bei der ersten Ausführung der Anwendung durch einen neuen Benutzer erstellt. Ein nicht standardmäßiger Wert wird dann in eine Benutzerbereichseinstellung geschrieben. Diese Einstellungen sind in der Datei app.config im Abschnitt <userSettings> definiert. Die Standard- und Anfangswerte der Einstellungen sind ebenfalls in der Datei app.config definiert. Die Datei app.config sieht somit folgendermaßen aus:

  <userSettings>
    <MySettingsDemo.MySettings>
      <setting name="LastSearchedItem" serializeAs="String">
        <value />
      </setting>
      <setting name="FormSize" serializeAs="String">
        <value>400, 400</value>
      </setting>
      <setting name="FormLocation" serializeAs="String">
        <value>0, 0</value>
      </setting>
    </MySettingsDemo.MySettings>
  </userSettings>

Benutzerbereichseinstellungen sind zum Speichern von Anwendungsvoreinstellungen hervorragend geeignet, die in der Regel für jeden Benutzer unterschiedlich sind. Als Benutzerbereichseinstellungen gelten beispielsweise Anzeigeeinstellungen wie Schriftgrad, Fensterposition und MRU-Listen.

Diese Architektur zeichnet sich durch eine hohe Flexibilität aus, da eine Anwendung auf Grundlage dieser Architektur für jeden Benutzer Einstellungen und Voreinstellungen speichern kann, selbst wenn die Anwendung in einem Szenario mit eingeschränkter Vertrauenswürdigkeit ausgeführt wird.

Erstellen einer Einstellung

Angenommen, Sie haben ein Suchfeld in Ihre Anwendung eingebaut und möchten den Wert des zuletzt gesuchten Elements speichern. Zunächst müssen Sie, wie in Abbildung 2 dargestellt, die erforderlichen Elemente der Benutzeroberfläche (UI) für die Anwendung erstellen.

Erstellen der Benutzeroberfläche für ein Suchfeld
Abbildung 2: Erstellen der Benutzeroberfläche für ein Suchfeld

Als Nächstes müssen Sie die Einstellung für die zuletzt eingegebene Suchzeichenfolge erstellen. Das vollständige Sucheingabefeld ist in Abbildung 3 als Beispiel dargestellt.

  1. Doppelklicken Sie im Projektmappen-Explorer auf My Project (Eigene Projekte).

  2. Klicken Sie auf die Registerkarte Settings (Einstellungen), um den Einstellungs-Designer anzuzeigen.

  3. Geben Sie einen Namen, einen Typ und einen Bereich für die Einstellung ein (LastSearchedItem, String und User).

  4. Geben Sie in der Spalte Value (Wert) einen Anfangswert für diese Einstellung ein (Wonach möchten Sie suchen?). Sie können dieses Feld auch frei lassen.

Vollständiges Suchfeld
Abbildung 3: Vollständiges Suchfeld

Hintergrundinformationen über eine Einstellung

Beim Hinzufügen einer neuen Einstellung im Einstellungs-Designer werden verschiedene Vorgänge im Hintergrund ausgeführt. Zunächst wird in der Datei app.config ein Eintrag hinzugefügt, der die Abschnitte zur Definition der Einstellungen definiert.

  <configSections>
    <sectionGroup 
name="applicationSettings"type="System.Configuration.ApplicationSettingsGroup, System, 
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="MySettingsDemo.MySettings" 
type="System.Configuration.ClientSettingsSection, System, 
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </sectionGroup>
  </configSections>

Im nächsten Schritt wird die Einstellungsdefinition in die Datei app.config eingefügt (siehe unten). In Abhängigkeit vom Typ der definierten Einstellung, werden die Abschnitte applicationSettings, userSettings und/oder connectionStrings angezeigt, je nachdem, welche Einstellungen von Ihnen definiert werden.

<userSettings>
    <MySettingsDemo.MySettings>
      <setting name="LastSearchedItem" serializeAs="String">
        <value />
      </setting>
      <setting name="FormSize" serializeAs="String">
        <value>400, 400</value>
      </setting>
      <setting name="FormLocation" serializeAs="String">
        <value>0, 0</value>
      </setting>
    </MySettingsDemo.MySettings>
  </userSettings>
  <connectionStrings>
    <add name="MySettingsDemo.MySettings.ConnectionString" 
connectionString="Server=TABLET; User ID=sa; Password=1234; 
Database=Northwind; Persist Security Info=True" 
providerName="System.Data.SqlClient" />
  </connectionStrings>
  <applicationSettings>
    <MySettingsDemo.MySettings>
      <setting name="SMTPServerIP" serializeAs="String">
        <value>192.168.2.11</value>
      </setting>
      <setting name="MyServicesURL" serializeAs="String">
        <value>https://localhost/MyServices/Service1.asmx</value>
      </setting>
    </MySettingsDemo.MySettings>
  </applicationSettings>

Zugreifen auf Einstellungen

Nachdem eine Einstellung hinzugefügt wurde, ist diese Einstellung abzurufen und zu aktualisieren. Der Vorgang zum Abrufen einer Einstellung ist sehr einfach und kann wie folgt ausgeführt werden:

My.Settings.LastSearchedItem

In Abbildung 4 wird dargestellt, wie Sie über IntelliSense auf die Einstellungsfelder Ihrer Anwendung zugreifen können. Auf diese überaus einfache Weise kann der benötigte Einstellungswert schnell gefunden werden.

IntelliSense-Funktion in der Anwendung
Abbildung 4: IntelliSense-Funktion in der Anwendung

Eine weitere Möglichkeit zur Verwendung einer Einstellung besteht darin, diese Einstellung an eine Eigenschaft zu binden. Dazu ist sehr wenig Code erforderlich. Beispielsweise können Sie die FormLocation-Einstellung an die Location-Eigenschaft des Formulars binden.

  • Erweitern Sie im Eigenschaftenfenster des Formulars die Einträge Data | (ApplicationSettings) | (PropertyBinding).

  • Suchen Sie die Location-Eigenschaft und wählen Sie die FormLocation-Einstellung aus (siehe Abbildung 5).

Auswählen der Einstellung "FormLocation"
Abbildung 5: Auswählen der Einstellung "FormLocation"

Dadurch wird im Designer der Code in der CodeBehind-Klasse Ihres Formulars erstellt:

Me.DataBindings.Add(New System.Windows.Forms.Binding("Location", 
MySettingsDemo.MySettings.Value, "FormLocation", True, 
MySettingsDemo.MySettings.Value.LastSearchedItem, Nothing, 
System.Windows.Forms.BindingUpdateMode.OnPropertyChanged))

Beachten Sie den letzten Parameter in der Binding-Klassenkonstruktion. Durch diesen Parameter wird der Aktualisierungsmodus der Einstellung definiert. Sie können hierbei festlegen, dass die Einstellung jeweils bei Änderung, bei Überprüfung oder nie aktualisiert wird. Durch den vom Designer generierten Standardcode wird die Einstellung jeweils bei Änderung aktualisiert.

Wenn Sie Einstellungen an Eigenschaften binden, müssen Sie sich keine Gedanken über das Lesen oder Schreiben der Einstellungen machen. Die Eigenschaft wird bei Bedarf automatisch festgelegt. Wenn sich der Wert der Eigenschaft ändert, wird dieser ebenfalls automatisch gespeichert. Dies geschieht, ohne dass Sie eine einzige Codezeile schreiben müssen.

Hinweis Die Einstellungen werden nur in bestimmten Projekttypen automatisch gespeichert, z. B. in Visual Basic Windows Forms-Anwendungen. In anderen Fällen, z. B. in Klassenbibliotheks-Projekten, müssen Sie die Save-Methode der My.Settings-Klasse explizit aufrufen.

Wenn die Eigenschaft im Fenster der Eigenschaftsbindung nicht aufgeführt ist, können Sie das gewünschte Ergebnis auch mit dem entsprechenden Code erzielen. Aus bestimmten Gründen steht die Size-Eigenschaft nicht als eine bindungsfähige Eigenschaft zur Verfügung. Dies ist auf eine Design-Entscheidung für die aktuelle Version zurückzuführen. In der Endversion werden jedoch alle Eigenschaften zur Bindung verfügbar sein. Hierfür fügen Sie der DataBindings-Auflistung Ihres Formulars eine neue Binding-Klasse hinzu. Die Binding-Klasse dient zur Definition des Eigenschafts- und des Einstellungsnamens sowie des Datenspeichers und des Aktualisierungsmodus. Somit können Sie zum Binden der Size-Eigenschaft an die FormSize-Einstellung die Bindung im Load-Ereignis Ihres Formulars manuell erstellen:

Me.DataBindings.Add(New System.Windows.Forms.Binding("Size", _
                    MySettingsDemo.MySettings.Value, _
                    "FormSize"))

 

Erweiterte Einstellungen

Wenn Sie mehr Kontrolle über die Einstellungen benötigen, können Sie eine eigene Klasse definieren, die von der ApplicationSettingsBase, der übergeordneten Klasse aller Einstellungsklassen, abgeleitet wird. Sie können hierbei jede Einstellung als eine Eigenschaft definieren, für die jeweils eine Get- und eine Set-Methode definiert wird. Wenn es sich um eine Anwendungsbereichs-Einstellung handelt, wird diese Eigenschaft mit dem Attribut ApplicationScopedSettingAttribute ausgestattet, bei einer Benutzerbereichs-Einstellung wird das Attribut UserScopedSettingAttribute zugewiesen. Genau diese Vorgänge werden auch durch den Einstellungs-Designer ausgeführt. Das nachstehende Beispiel enthält einen Auszug aus der Datei MySettings.vb, die durch den Einstellungs-Designer generiert wird:

Partial NotInheritable Class MySettings
    Inherits System.Configuration.ApplicationSettingsBase
 
    <System.Diagnostics.DebuggerNonUserCode(),  _
     System.Configuration.UserScopedSettingAttribute(),  _
     System.Configuration.DefaultSettingValueAttribute("400, 400")>  _
    Public Property FormSize() As System.Drawing.Size
        Get
            Return CType(Me("FormSize"),System.Drawing.Size)
        End Get
        Set
            Me("FormSize") = value
        End Set
    End Property
    
    <System.Diagnostics.DebuggerNonUserCode(),  _
     System.Configuration.SpecialSetting(System.Configuration.SpecialSetting.ConnectionString),  _
     System.Configuration.ApplicationScopedSettingAttribute(),  _
     System.Configuration.DefaultSettingValueAttribute("Server=TABLET; 
User ID=sa; Password=1234; Database=Northwind; Persist Security In"& _ 
        "fo=True")>  _
    Public ReadOnly Property ConnectionString() As String
        Get
            Return CType(Me("ConnectionString"),String)
        End Get
    End Property
    
    <System.Diagnostics.DebuggerNonUserCode(),  _
     System.Configuration.ApplicationScopedSettingAttribute(),  _
     System.Configuration.DefaultSettingValueAttribute("192.168.2.11")>  _
    Public ReadOnly Property SMTPServerIP() As String
        Get
            Return CType(Me("SMTPServerIP"),String)
        End Get
    End Property
...

Hinweis Verbindungszeichenfolgen werden durch das SpecialSetting-Attribut ergänzt und in der CONFIG-Datei in einem eigenen Bereich erstellt.

Beachten Sie ebenfalls, dass es sich hierbei um eine Partial-Klasse handelt, d. h. Sie können in dem Projekt eine andere Datei und einen weiteren Teil für diese Klasse erstellen. Mit dieser Vorgehensweise können Sie die Einstellungen optimieren, ohne die vom Designer generierte Datei bearbeiten zu müssen. Sie können dieser Klasse eine Ereignisbehandlung hinzufügen, um die Einstellungen noch genauer zu steuern. Sie können die folgenden drei Ereignisse behandeln:

  • SettingChanging

  • SettingsSaving

  • PropertyChanging

Es ist zu beachten, dass die Einstellungsfeatures auf einer Infrastruktur mit austauschbaren Providern aufgesetzt sind. Derzeit enthält Visual Studio 2005 nur einen Provider (LocalFileSettingsProvider), der auf CONFIG-Dateien zugreifen kann. Sie können diesen Provider auch durch alternative Provider ersetzen oder ergänzen. Ein gutes Beispiel hierfür ist das Settings-in-a-Cloud-Szenario, bei dem ein Webdienst zum Speichern von Einstellungen in einer Datenbank verwendet wird. Die Einstellungen können dann von jedem beliebigen Ort aus abgerufen werden, an dem sich ein Benutzer anmeldet.

 

Schlussbemerkung

In früheren Architekturen zur Behandlung von Anwendungs-Einstellungen gab es bestimmte Beschränkungen. Durch die neue Architektur im .NET Framework 2.0 werden viele dieser Probleme gelöst. Die neue Architektur vereinfacht in hohem Maße die Erstellung und Bindung sowie das Abrufen und Aktualisieren von Einstellungen, wie in diesem Artikel anhand von Visual Basic 2005 dargestellt. In der neuen Architektur werden auch Anwendungsbereichs- und Benutzerbereichs-Einstellungen definiert. Diese neue Architektur wird ohne Zweifel zu Produktivitätssteigerungen führen und es Entwicklern ermöglichen, sich auf die Lösung eines Geschäftsproblems zu konzentrieren, anstatt Tage oder sogar Wochen damit zu verbringen, sich in der komplexen Problematik von Anwendungs-Einstellungen zurechtzufinden.

Emad Ibrahim (MCSD, MCAD) ist technischer Entwickler bei Optimal Solutions Integration, Inc (in Englisch).