ApplicationSettingsBase 没有按预期序列化我的 类

ApplicationSettingsBase is not serializing my classes as expected

我正在尝试使用 ApplicationSettingsBase 来保存我的 classes。我这里有一个例子。我也尝试过不使用 ApplicationSettingsBase 并且似乎工作正常。该示例在下面。

有人可以指导我使用 ApplicationSettingsBase 来保存完整的 class 层次结构吗?谢谢,谢谢。

我在第一个示例中保存了一些中间实例以尝试解决这个问题。我不打算在最终实施中这样做。我可以在这里看到它会保存中间数据而不是嵌套数据。就是不明白。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;

// prefs is defined in Settings.settings with the name prefs, type WindowsFormsApplication1.Prefs, user scope, and no default value.

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

            Properties.Settings.Default.prefs = new Prefs();

            Test test = new Test();
            test.steps.Add("Step1");
            test.steps.Add("Step2");

            Properties.Settings.Default.prefs.tests.Add(test);

            test.Save();
            Properties.Settings.Default.Save();
            Properties.Settings.Default.prefs.Save();

            Environment.Exit(0);
        }
    }

    // WindowsFormsApplication1.Prefs
    public class Prefs : ApplicationSettingsBase
    {
        [UserScopedSetting]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public List<Test> tests
        {
            get { return ((List<Test>)(this["tests"])); }
            set { this["tests"] = value; }
        }

        public Prefs()
        {
            tests = new List<Test>();
        }
    }

    public class Test : ApplicationSettingsBase
    {
        [UserScopedSetting]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public string name
        {
            get { return ((string)(this["name"])); }
            set { this["name"] = value; }
        }

        [UserScopedSetting]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public List<string> steps
        {
            get { return ((List<string>)(this["steps"])); }
            set { this["steps"] = value; }
        }

        public Test()
        {
            name = "NoName";
            steps = new List<string>();
        }

    }
}

user.config 在 运行 之后:

/*
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="WindowsFormsApplication1.Prefs" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        <section name="WindowsFormsApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        <section name="WindowsFormsApplication1.Test" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
</configSections>
<userSettings>
    <WindowsFormsApplication1.Prefs>
        <setting name="tests" serializeAs="Xml">
            <value />
        </setting>
    </WindowsFormsApplication1.Prefs>
    <WindowsFormsApplication1.Properties.Settings>
        <setting name="prefs" serializeAs="Xml">
            <value />
        </setting>
    </WindowsFormsApplication1.Properties.Settings>
    <WindowsFormsApplication1.Test>
        <setting name="steps" serializeAs="Xml">
            <value>
                <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <string>Step1</string>
                    <string>Step2</string>
                </ArrayOfString>
            </value>
        </setting>
        <setting name="name" serializeAs="Xml">
            <value>
                <string>NoName</string>
            </value>
        </setting>
    </WindowsFormsApplication1.Test>
</userSettings>
</configuration>
*/

这是没有尝试使用 ApplicationSettingsBase 的示例:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;

// prefs is defined in Settings.settings with the name prefs, type WindowsFormsApplication1.Prefs, user scope, and no default value.

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

            Properties.Settings.Default.prefs = new Prefs();

            Test test = new Test();
            test.steps.Add("Step1");
            test.steps.Add("Step2");

            Properties.Settings.Default.prefs.tests.Add(test);

            Properties.Settings.Default.Save();

            Environment.Exit(0);
        }
    }

    // WindowsFormsApplication1.Prefs
    public class Prefs
    {
        public List<Test> tests { get; set; }
        public Prefs()
        {
            tests = new List<Test>();
        }
    }

    public class Test
    {
        public string name { get; set; }
        public List<string> steps { get; set; }

        public Test()
        {
            name = "NoName";
            steps = new List<string>();
        }
    }
}

user.config 在 运行 之后:

/*
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="WindowsFormsApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
</configSections>
<userSettings>
    <WindowsFormsApplication1.Properties.Settings>
        <setting name="prefs" serializeAs="Xml">
            <value>
                <Prefs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <tests>
                        <Test>
                            <name>NoName</name>
                            <steps>
                                <string>Step1</string>
                                <string>Step2</string>
                            </steps>
                        </Test>
                    </tests>
                </Prefs>
            </value>
        </setting>
    </WindowsFormsApplication1.Properties.Settings>
</userSettings>
</configuration>
*/

几乎回答了我的问题:

In particular, Properties.Settings.Default would normally return an instance of a Designer-created class named Settings. Calling Properties.Settings.Default.Save(); will save only the values in that object, not those in some other class.

If you have a separate class DeviceConfiguration that you want saved (as you seem to in the code you posted), you need to handle that explicitly. Simply having an instance of a subclass of ApplicationSettingsBase won't do it. You need to call the Save() method on that custom subclass yourself.

我没有意识到我的自定义结构不必放在 Properties.Settings 中就可以保存到 user.config 文件中。