I am attempting to use ApplicationSettingsBase to persist my classes. I have an example here. I also tried without using ApplicationSettingsBase and that seems to work fine. That example is further below.
Can someone give me some guidance on using ApplicationSettingsBase to persist my full class hierarchy? Thank you, thank you.
I am saving some intermediate instances in the first example to try to figure this out. I'm not planning on doing that in the final implementation. I can see here that it will save the intermediate data but not the nested one. I just don't understand.
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 after run:
/*
<?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>http://stackoverflow.com/questions/13798528/servicestack-text-does-not-serialize-my-object-as-expected
</configuration>
*/
Here is the example without trying to useApplicationSettingsBase:
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 after run:
/*
<?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>
*/
This answer pretty much nailed my question:
In particular,
Properties.Settings.Default
would normally return an instance of a Designer-created class namedSettings
. CallingProperties.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 ofApplicationSettingsBase
won't do it. You need to call theSave()
method on that custom subclass yourself.
I did not realize that my custom structure did not have to be placed within Properties.Settings
for it to get saved to the user.config
file.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.