7 Stimmen

Wie speichere ich eine benutzerdefinierte Klasse in den Benutzereinstellungen mit ApplicationSettingsBase?

Ich versuche, eine benutzerdefinierte Klasse in den Benutzereinstellungen zu speichern, habe aber nicht viel Erfolg.

Ich habe ein Testprojekt in Visual Studio 2010 mit Target framework = ".NET Framework 4" erstellt. Das Hauptformular hat zwei Textfelder für die Anzeige und Bearbeitung eines einfachen Teststrings und des Feldes "Titel" aus meiner benutzerdefinierten Klasse; zusammen mit zwei Schaltflächen zum Laden und Speichern der Einstellungen.

Schließlich fügte ich zwei Einstellungen hinzu: "TestString" (ein einfacher String-Wert) und TestData (Typ von MyDataClass - ich tat dies auf der Registerkarte "Eigenschaften.Einstellungen" des Projekts, indem ich "Durchsuchen..." aus der Dropdown-Liste "Typ" auswählte und dann manuell "MyUserSettingsTest.MyDataClass" in das Feld "Ausgewählter Typ" eintrug, da es ursprünglich nicht in der Liste der verfügbaren Typen erschien, später aber doch.)

Wenn ich die Anwendung starte und auf LoadSettings klicke, lädt der Event-Handler die einfache Zeichenkette und MyData oder, falls dies fehlschlägt, erstellt eine neue Instanz von MyDataClass. Ich kann dann die einfache Zeichenfolge und die Testdaten Title im Formular bearbeiten und auf SaveSettings klicken. Wenn ich dann die Werte erneut bearbeite und erneut auf LoadSettings klicke, werden die zuletzt gespeicherten Werte wie erwartet für beide Werte wiederhergestellt. So weit, so gut.

Das Problem ist, dass nach dem Beenden der Anwendung und dem Neustart die einfache Testzeichenfolge wiederhergestellt wird, das MyData-Objekt jedoch nicht! Offensichtlich ist der Code persistieren MyData in den Speicher ok, aber nicht auf den permanenten Speicher?

Der Code des Hauptformulars lautet:

using System;
using System.Windows.Forms;

namespace MyUserSettingsTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public MyDataClass MyData {get;set;}

        private void loadSettingsButton_Click(object sender, EventArgs e)
        {
            this.myTextBox.Text = Properties.Settings.Default.TestString;
            this.MyData = Properties.Settings.Default.TestData;

            if (this.MyData == null)
            {
                this.MyData = new MyDataClass() { ID = 1, Title = "Default New Title" };
            }

            this.myDataTitleTextBox.Text = this.MyData.Title;
        }

        private void saveSettingsButton_Click(object sender, EventArgs e)
        {
            this.MyData.Title = this.myDataTitleTextBox.Text;

            Properties.Settings.Default.TestString = this.myTextBox.Text;
            Properties.Settings.Default.TestData = this.MyData;
            Properties.Settings.Default.Save();
        }
    }
}

Der Code meiner Testdatenklasse lautet:

using System.Configuration;

namespace MyUserSettingsTest
{
    public class MyDataClass : ApplicationSettingsBase
    {
        public MyDataClass()
        {
        }

        private int _id;
        private string _title;

        [UserScopedSetting()]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)] 
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        [UserScopedSetting()]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)] 
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }
    }
}

Ich weiß nicht, ob es hilfreich ist, aber die automatisch generierte app.config-Datei (die die Einstellung für TestString, aber NICHT TestData enthält!!?) ist es:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
            <section name="MyUserSettingsTest.Properties.Settings"     type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
        </sectionGroup>
    </configSections>
    <userSettings>
        <MyUserSettingsTest.Properties.Settings>
            <setting name="TestString" serializeAs="String">
                <value/>
            </setting>
        </MyUserSettingsTest.Properties.Settings>
    </userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

Die automatisch generierte Datei Settings.Designer.cs lautet:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.269
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace MyUserSettingsTest.Properties {

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

    public static Settings Default {
        get {
            return defaultInstance;
        }
    }

    [global::System.Configuration.UserScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("")]
    public string TestString {
        get {
            return ((string)(this["TestString"]));
        }
        set {
            this["TestString"] = value;
        }
    }

    [global::System.Configuration.UserScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public global::MyUserSettingsTest.MyDataClass TestData {
        get {
            return ((global::MyUserSettingsTest.MyDataClass)(this["TestData"]));
        }
        set {
            this["TestData"] = value;
        }
    }
}
}

Kann mir bitte jemand sagen, was ich falsch mache oder was ich zusätzlich tun muss, um meine benutzerdefinierte Klasse zu erhalten, um die Benutzereinstellungen richtig zu erhalten.

2voto

Shahzad Qureshi Punkte 1667

Speichern Sie Ihr benutzerdefiniertes Objekt als serialisierte Zeichenfolge. Dann brauchen Sie nur eine Zeichenkette zu speichern. Verwenden Sie zum Beispiel den Json .NET JsonConverter, um Objekte zu serialisieren und zu deserialisieren.

Properties.Settings.Default.TestData = JsonConvert.SerializeObject<MyDataClass>(this.MyData);

Dann könnten Sie es so zurücklesen

this.MyData = JsonConvert.DeserializeObject<MyDataClass>(Properties.Settings.Default.TestData);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X