c# Windows Forms:如何在运行时创建新的设置,以便它们永久保存为Settings.Default - 值?
如果仍然有人关心,可以通过Settings.Default.Properties.Add(...)
动态添加设置,并在保存后将这些设置持久化到本地存储中(我发现这些条目被反映在漫游文件中)。
不过,在重新加载后,动态添加的设置似乎会在Settings.Default.Properties
集合中丢失。
我可以通过在首次访问前添加动态属性来解决此问题。 例如(请注意,我从基本设置“创建”了我的动态设置):
// create new setting from a base setting:
var property = new SettingsProperty(Settings.Default.Properties["<baseSetting>"]);
property.Name = "<dynamicSettingName>";
Settings.Default.Properties.Add(property);
// will have the stored value:
var dynamicSetting = Settings.Default["<dynamicSettingName>"];
我不知道 Microsoft 是否支持此功能,因为关于这个主题的文档非常少。
问题在此处也有描述:http://www.vbdotnetforums.com/vb-net-general-discussion/29805-my-settings-run-time-added-properties-dont-save.html#post88152,提供了一些解决方案:http://msdn.microsoft.com/en-us/library/saa62613(v=VS.100).aspx(请参见社区内容 - 标题为“如何创建 / 保存 / 加载动态(运行时)设置”)。但这是 VB.NET。
除了John的保存解决方案外,正确的加载方法是添加属性,然后在设置中执行Reload()。
您的动态设置将保留下来!
对于完整的示例,在库代码中使用有效,因为您可以传递设置..
ApplicationSettingsBase settings = passed_in;
SettingsProvider sp = settings.Providers["LocalFileSettingsProvider"];
SettingsProperty p = new SettingsProperty("your_prop_name");
your_class conf = null;
p.PropertyType = typeof( your_class );
p.Attributes.Add(typeof(UserScopedSettingAttribute),new UserScopedSettingAttribute());
p.Provider = sp;
p.SerializeAs = SettingsSerializeAs.Xml;
SettingsPropertyValue v = new SettingsPropertyValue( p );
settings.Properties.Add( p );
settings.Reload();
conf = (your_class)settings["your_prop_name"];
if( conf == null )
{
settings["your_prop_name"] = conf = new your_class();
settings.Save();
}
SettingsPropertyValue
- 这一行可以省略。这就是为什么@Drew的代码能够工作,尽管不如它本应该的那样高效 :-) - JonP由于Settings类是在构建时生成的(或者说,每当您从设计师中更新设置文件时),因此您无法将此机制用于动态场景。但是,您可以向应用程序设置添加一些集合或字典,并在运行时动态修改它们。
您不能直接添加设置(至少不在运行时编辑配置XML),但可以伪造它。
在我的情况下,我在表单上有一组相同的自定义控件,并且我想存储每个控件的运行时状态。我需要存储每个控件的状态,因为每个控件都有不同的数据。
我创建了一个名为ControlData的新的StringCollection设置,并将自己的数据放入其中。然后,我从该列表中加载数据并用它来初始化我的控件。
该列表如下:
Box1Text=A
Box1List=abc;def;foo;bar;
Box2Text=hello
Box2List=server1;server2;
在我的启动代码中,我像这样读取键/值对:
foreach (string item in Properties.Settings.Default.ControlData) {
string[] parts=item.split('=');
parts[0]将会有键,parts[1]将会有值。你现在可以根据这个数据进行操作。
在关闭阶段,我会反过来将数据写回列表。(遍历表单中的所有控件,并将它们的设置添加到ControlData中)。
如何访问您创建的新设置?Visual Studio设置设计器的重点是,您可以编写使用这些设置的代码,并在编译时检查您的代码。如果您想动态创建应用程序要使用的新设置,则还需要动态加载它们。对于动态设置,您可能需要查看System.Configuration程序集,特别是ConfigurationSection。您可以使用它创建自定义配置部分,用于动态设置添加/删除。您可以使用ConfigurationCollection进行动态添加/删除。
INI文件?Google找到了this INI library适用于.NET。
RegistryKey ProgSettings = Registry.CurrentUser.OpenSubKey("Software", true);
ProgSettings.CreateSubKey("Your Program settings");
ProgSettings.Close();
RegistryKey ProgSettings = Registry.CurrentUser.OpenSubKey("Software\\Your Program settings", true);
ProgSettings.SetValue("Setting Name", value); // store settings
string settings = ProgSettings.GetValue("Setting Name", false); // retreave settings
ProgSettings.DeleteValue("Setting Name", false);
在操作注册表时,请确保在完成后关闭注册表键,以避免与可能写入注册表的程序其他部分发生冲突。
许多商业软件应用程序使用这些方法。 stackoverflow有很多关于写入和读取注册表的示例。 这比修改创建设置时使用的appconfig.xml文件要容易得多。
我花了很长时间,使用这里的前两个答案,以及这个链接 (在运行时创建新设置,并在重启后读取) ,最终使其工作。
首先,设定你的期望。这里的答案将创建一个新的用户设置,下次启动应用程序时,您可以获取其值。然而,通过这种方式创建的设置不会出现在设置设计器中。实际上,当您重新启动应用程序并尝试在代码中访问设置时,它将找不到该设置。但是,您通过代码创建的设置已保存在用户配置文件中 (例如jDoe.config),保存在文件系统中的某个位置。为了访问这个值,您必须再次添加设置。
以下是我拥有的可行示例:
private void FormPersistence_Load(object sender, EventArgs e)
{
StartPosition = FormStartPosition.Manual;
// Set window location
var exists = Settings.Default.Properties.OfType<SettingsProperty>().Any(p => p.Name == Name + "Location");
if (exists)
{
this.Location = (Point)Settings.Default[Name + "Location"];
}
else
{
var property = new SettingsProperty(Settings.Default.Properties["baseLocation"]);
property.Name = Name + "Location";
Settings.Default.Properties.Add(property);
Settings.Default.Reload();
this.Location = (Point)Settings.Default[Name + "Location"];
}
}
我明白我原本想法是错误的。我正在将一个C++应用程序移植到C#,它有很多ini文件设置,我正在寻找一种快捷方式来添加它们。我有点懒。
Properties.Settings.Default.Save()
;不确定是否需要,因为 John 的答案中没有提到。 - Ruben9922