我一直在Properties.Settings.Default
对象中存储用户设置的集合,并使用Visual Studio设置设计器(右键单击项目,单击“属性”,然后单击“设置”选项卡)来设置事物起来。最近,一些用户抱怨说这个特定设置跟踪的数据是随机丢失的。
为了给出一个想法(不知道我是怎么做的,但有些接近),它的工作方式是我有一个对象,如下:
class MyObject
{
public static string Property1 { get; set; }
public static string Property2 { get; set; }
public static string Property3 { get; set; }
public static string Property4 { get; set; }
}
然后在代码中,我可能会这样做以保存信息:
public void SaveInfo()
{
ArrayList userSetting = new ArrayList();
foreach (Something s in SomeCollectionHere) // For example, a ListView contains the info
{
MyObject o = new MyObject {
Property1 = s.P1;
Property2 = s.P2;
Property3 = s.P3;
Property4 = s.P4;
};
userSetting.Add(o);
}
Properties.Settings.Default.SettingName = userSetting;
}
现在,把它拉出来的代码是这样的:
public void RestoreInfo()
{
ArrayList setting = Properties.Settings.Default.SettingName;
foreach (object o in setting)
{
MyObject data = (MyObject)o;
// Do something with the data, like load it in a ListView
}
}
我还确保用[global::System.Configuration.SettingsSerializeAs(global::System.Configuration.SettingsSerializeAs.Binary)]
装饰Settings.Designer.cs文件,如下所示:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SettingsSerializeAs(global::System.Configuration.SettingsSerializeAs.Binary)]
public global::System.Collections.ArrayList SettingName
{
get {
return ((global::System.Collections.ArrayList)(this["SettingName"]));
}
set {
this["SettingName"] = value;
}
}
现在,随机,信息将消失。我可以对此进行调试,并看到Properties.Settings.Default
为ArrayList
返回空SettingName
。我真的不想使用ArrayList,但我没有看到以这种方式存储泛型集合的方法。
我即将放弃并使用纯XML保存此信息。我只是想验证我确实在推动.NET基础架构这么远。我是对的吗?
答案 0 :(得分:1)
在Settings Designer类中使用SettingsSerializeAs二进制属性时,我有类似的经验。它在测试中起作用,但一段时间后它无法恢复属性值。
在我的情况下,随后通过设计师添加了设置。源代码控制历史记录显示在我不知情的情况下,Settings.SerializeAs属性已从Settings.Designer.cs中删除。
我添加了以下代码,以检查该属性是否意外丢失,相当于RestoreInfo()方法。
#if(DEBUG)
//Verify that the Property has the required attribute for Binary serialization.
System.Reflection.PropertyInfo binarySerializeProperty = Properties.Settings.Default.GetType().GetProperty("SettingName");
object[] customAttributes = binarySerializeProperty.GetCustomAttributes(typeof(System.Configuration.SettingsSerializeAsAttribute), false);
if (customAttributes.Length != 1)
{
throw new ApplicationException("SettingsSerializeAsAttribute required for SettingName property");
}
#endif
此外,仅因为您的示例中缺少它,请不要忘记调用Save。在调用SaveInfo()之后说。
Properties.Settings.Default.Save();
答案 1 :(得分:0)
从您的示例中我看不出有什么不正确的尝试。我认为您描述的问题的根源可能是您的汇编版本在变化?用户设置不会自动神奇地升级自己(至少我无法让他们自己升级)。
我很欣赏你的困境,几个月前我经历过这个。我编写了一个UserSettings类,它在命名组标题下提供标准名称/值对集合(KeyValueConfigurationElement),如下所示:
<configSections>
<section name="userSettings" type="CSharpTest.Net.AppConfig.UserSettingsSection, CSharpTest.Net.Library"/>
</configSections>
<userSettings>
<add key="a" value="b"/>
<sections>
<section name="c">
<add key="a" value="y"/>
</section>
</sections>
</userSettings>
无论如何,看看这是否符合您的需求,或者提供一些实现自定义ConfigurationSection的见解,以满足您的需求。
哦,是的,代码在这里:
答案 2 :(得分:0)
将“设置”功能与“用户”范围一起使用时,设置将保存到当前登录用户的“应用程序数据”(Vista / 7中的AppData)文件夹中。因此,如果UserA登录,使用您的应用程序,然后UserB登录,他将不会加载UserA的设置,他将拥有自己的。
在您要完成的任务中,我建议使用XmlSerializer
类来序列化对象列表。使用非常简单:
序列化:
ArrayList list = new ArrayList();
XmlSerializer s = new XmlSerializer(typeof(ArrayList));
using (FileStream fs = new FileStream(@"C:\path\to\settings.xml", FileMode.OpenOrCreate))
{
s.Serialize(fs, list);
}
要反序列化它:
ArrayList list;
XmlSerializer s = new XmlSerializer(typeof(ArrayList));
using (FileStream fs = new FileStream(@"C:\path\to\settings.xml", FileMode.Open))
{
list = (ArrayList)s.Deserialize(fs);
}