c#windows窗体:如何在运行时创建新设置,以便将它们永久保存为Settings.Default .-- values?
答案 0 :(得分:17)
以防万一对任何人都很重要:
您可以通过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。
答案 1 :(得分:15)
除了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();
}
答案 2 :(得分:7)
由于Settings类是在构建时生成的(或者实际上,每当您从设计器中更新设置文件时),您都无法将此机制用于动态方案。但是,您可以向应用程序设置添加一些集合或字典,并动态修改它。
答案 3 :(得分:2)
您可以做的是创建一个新的注册表项。 将新密钥命名为“您的程序设置”。
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文件。
答案 4 :(得分:2)
您无法直接添加设置(至少在运行时不编辑配置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('=');
部件[0]将具有键,部件[1]将具有该值。您现在可以根据这些数据进行处理。
在关闭阶段,我执行反向操作将数据写回列表。 (迭代表单中的所有控件并将其设置添加到ControlData。
答案 5 :(得分:1)
您将如何访问已创建的新设置? Visual Studio设置设计器的要点是,您可以编写使用这些设置的代码,并对代码进行编译时检查。如果要动态创建要使用的应用程序的新设置,还需要动态加载它们。对于动态设置,您可能需要查看System.Configuration程序集,尤其是ConfigurationSection。您可以使用该部分创建自定义配置部分,您可以将其用于动态设置添加/删除。您可以使用ConfigurationCollection进行动态添加/删除。
INI文件呃? Google为.NET提出了this INI library。
答案 6 :(得分:0)
我看到我想要的是错误的想法。我正在将一个c ++应用程序移植到c#,它有很多ini文件设置,我正在寻找一个添加它们的快捷方式。我很懒。
答案 7 :(得分:0)
我花了很长时间使用此处的前两个答案以及此链接(Create new settings on runtime and read after restart)才能使它最终生效。
首先,设定您的期望。这里的答案将创建一个新的用户设置,您可以在下次启动应用程序时获得其价值。但是,以这种方式创建的设置将不会出现在“设置”设计器中。实际上,当您重新启动应用程序并尝试访问代码中的设置时,它将找不到它。但是,通过代码创建的设置将保存在文件系统中某个位置的user.config文件(例如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"];
}
}
注意:
我的新设置名称将在运行时解析。名称实际上是this.Name,即表单的名称。这是其他表单可以继承的基本表单,因此所有子表单都可以记住其位置。
baseLocation是我在“设置”设计器中手动创建的设置。我的新设置是同一类型。这样,我不必担心代码中的提供者,类型等问题。