C#Windows窗体。
我已成功使用应用程序设置来保存和加载用户设置,以获取表单上控件的值。我有一个复选框和代码,可以在其中设置是否自动发生(在应用程序启动和关闭时)。我还有一个菜单,因此我可以加载它们并在运行时保存它们。全部使用默认的user.config。
示例。在“应用程序设置”中,我拥有该功能(对于其中一项,这是一个名为RbBitRate6Mbps的单选按钮):
名称:BitRate6Mbps
类型:字符串
范围:用户
值:False
要保存设置,我有一个菜单项,保存默认值。运行:
if (RbBitRate6Mbps.Checked == true)
{
Settings.Default["BitRate6Mbps"] = "True";
}
else
{
Settings.Default["BitRate6Mbps"] = "False";
}
Settings.Default.Save();
要重新加载设置,我有一个菜单项Load Defaults。运行:
if (Settings.Default["BitRate6Mbps"].ToString() == "True")
{
RbBitRate6Mbps.Checked = true;
}
else
{
RbBitRate6Mbps.Checked = false;
}
在上面的其余代码中,我还保存和加载了大约10个其他控件(文本框,复选框和单选按钮)。这一切都没有问题。
现在,我希望有几组这些设置,每组将包含一些相同的值和一些不同的值。每个文件都有一个不同的文件名,并保存到自定义位置(默认情况下为应用程序文件夹)。我不介意文件的格式是什么(xml,ini等),但是如果与默认格式相同,那就很好了。
我已经创建了新的菜单项,保存自定义设置和加载自定义设置。
我已经添加了SaveFileDialog和LoadFileDialog,希望可以用于上述操作。但是,如果不需要这些,那也很好。
这是我陷入困境的地方。
我一直在寻找几天的方法的明确示例。我一直找不到很多东西。我所发现的,我一直无法理解文档。
我认为重新载入设置会更容易一些吗?但是我也认为,为了保存文件,请使用:
Settings.Default.Save();
将无法完成我的目标,因为它只会写入默认的user.config文件?
我想做什么?
如果有人有任何说明和示例代码?
使用OpenExeConfiguration
功能读取设置,然后在Save
返回之前先添加/更新键值。最后,您可以ConfigurationManager.RefreshSection
刷新特定部分的设置。
Link的示例
static void AddUpdateAppSettings(string key, string value)
{
try
{
var configFile = ConfigurationManager
.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
if (settings[key] == null)
{
settings.Add(key, value);
}
else
{
settings[key].Value = value;
}
configFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
}
catch (ConfigurationErrorsException)
{
Console.WriteLine("Error writing app settings");
}
}
更新。我已经安装了新的设置提供程序,并且正在工作。将XML保存到app文件夹。它可能支持多个配置文件(因为我支持更改文件名)。由于开发人员正在帮助我,我也正在测试PeanutButter ini。当/如果我能正常工作,我将在这里详细介绍。
以下是设置新的设置提供程序的说明:
在我的测试应用中,我的设置如下:
Name: FullName
Type: String
Scope: User
Value: John Doe
Name: School
Type: String
Scope: User
Value: Oxford
Name: Class
Type: String
Scope: User
Value: 4B
从NuGet安装新的设置提供程序(在解决方案资源管理器中,右键单击:引用。然后选择:管理NuGet软件包。然后搜索:PortableSettingsProvider。安装它。)]] >>
在Program.cs中,修改static void Main()
。添加以下行:PortableSettingsProvider.ApplyProvider(Properties.Settings.Default);Properties.Settings.Default.Reset();
我的现在看起来像这样:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
PortableSettingsProvider.ApplyProvider(Properties.Settings.Default);
Properties.Settings.Default.Reset();
Application.Run(new FlakieADBGUI());
}
我的外观如下所示(我不确定是否全部必要,但会在实际应用上线之前进行整理)。添加任何缺少的内容:
using System;
using System.Windows.Forms;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration;
using System.Xml.Linq;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bluegrams.Application;
仍然在Program.cs中,在static void Main()
行的下面,添加以下代码(对不起,这很长)。很抱歉,我找不到指向实际文件的链接。我会在可能的时候发布并删除此代码:/// <summary>
/// Provides portable, persistent application settings.
/// </summary>
public class PortableSettingsProvider : PortableSettingsProviderBase
{
/// <summary>
/// Specifies the name of the settings file to be used.
/// </summary>
public static string SettingsFileName { get; set; } = "portable.config";
public override string Name => "PortableSettingsProvider";
/// <summary>
/// Applies this settings provider to each property of the given settings.
/// </summary>
/// <param name="settingsList">An array of settings.</param>
public static void ApplyProvider(params ApplicationSettingsBase[] settingsList)
=> ApplyProvider(new PortableSettingsProvider(), settingsList);
private string ApplicationSettingsFile => Path.Combine(SettingsDirectory, SettingsFileName);
public override void Reset(SettingsContext context)
{
if (File.Exists(ApplicationSettingsFile))
File.Delete(ApplicationSettingsFile);
}
private XDocument GetXmlDoc()
{
// to deal with multiple settings providers accessing the same file, reload on every set or get request.
XDocument xmlDoc = null;
bool initnew = false;
if (File.Exists(this.ApplicationSettingsFile))
{
try
{
xmlDoc = XDocument.Load(ApplicationSettingsFile);
}
catch { initnew = true; }
}
else
initnew = true;
if (initnew)
{
xmlDoc = new XDocument(new XElement("configuration",
new XElement("userSettings", new XElement("Roaming"))));
}
return xmlDoc;
}
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
{
XDocument xmlDoc = GetXmlDoc();
SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
// iterate through settings to be retrieved
foreach (SettingsProperty setting in collection)
{
SettingsPropertyValue value = new SettingsPropertyValue(setting);
value.IsDirty = false;
//Set serialized value to xml element from file. This will be deserialized by SettingsPropertyValue when needed.
value.SerializedValue = getXmlValue(xmlDoc, XmlConvert.EncodeLocalName((string)context["GroupName"]), setting);
values.Add(value);
}
return values;
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
{
XDocument xmlDoc = GetXmlDoc();
foreach (SettingsPropertyValue value in collection)
{
setXmlValue(xmlDoc, XmlConvert.EncodeLocalName((string)context["GroupName"]), value);
}
try
{
// Make sure that special chars such as '\r\n' are preserved by replacing them with char entities.
using (var writer = XmlWriter.Create(ApplicationSettingsFile,
new XmlWriterSettings() { NewLineHandling = NewLineHandling.Entitize, Indent = true }))
{
xmlDoc.Save(writer);
}
}
catch { /* We don't want the app to crash if the settings file is not available */ }
}
private object getXmlValue(XDocument xmlDoc, string scope, SettingsProperty prop)
{
object result = null;
if (!IsUserScoped(prop))
return result;
//determine the location of the settings property
XElement xmlSettings = xmlDoc.Element("configuration").Element("userSettings");
if (IsRoaming(prop))
xmlSettings = xmlSettings.Element("Roaming");
else xmlSettings = xmlSettings.Element("PC_" + Environment.MachineName);
// retrieve the value or set to default if available
if (xmlSettings != null && xmlSettings.Element(scope) != null && xmlSettings.Element(scope).Element(prop.Name) != null)
{
using (var reader = xmlSettings.Element(scope).Element(prop.Name).CreateReader())
{
reader.MoveToContent();
switch (prop.SerializeAs)
{
case SettingsSerializeAs.Xml:
result = reader.ReadInnerXml();
break;
case SettingsSerializeAs.Binary:
result = reader.ReadInnerXml();
result = Convert.FromBase64String(result as string);
break;
default:
result = reader.ReadElementContentAsString();
break;
}
}
}
else
result = prop.DefaultValue;
return result;
}
private void setXmlValue(XDocument xmlDoc, string scope, SettingsPropertyValue value)
{
if (!IsUserScoped(value.Property)) return;
//determine the location of the settings property
XElement xmlSettings = xmlDoc.Element("configuration").Element("userSettings");
XElement xmlSettingsLoc;
if (IsRoaming(value.Property))
xmlSettingsLoc = xmlSettings.Element("Roaming");
else xmlSettingsLoc = xmlSettings.Element("PC_" + Environment.MachineName);
// the serialized value to be saved
XNode serialized;
if (value.SerializedValue == null || value.SerializedValue is string s && String.IsNullOrWhiteSpace(s))
serialized = new XText("");
else if (value.Property.SerializeAs == SettingsSerializeAs.Xml)
serialized = XElement.Parse((string)value.SerializedValue);
else if (value.Property.SerializeAs == SettingsSerializeAs.Binary)
serialized = new XText(Convert.ToBase64String((byte[])value.SerializedValue));
else serialized = new XText((string)value.SerializedValue);
// check if setting already exists, otherwise create new
if (xmlSettingsLoc == null)
{
if (IsRoaming(value.Property)) xmlSettingsLoc = new XElement("Roaming");
else xmlSettingsLoc = new XElement("PC_" + Environment.MachineName);
xmlSettingsLoc.Add(new XElement(scope,
new XElement(value.Name, serialized)));
xmlSettings.Add(xmlSettingsLoc);
}
else
{
XElement xmlScope = xmlSettingsLoc.Element(scope);
if (xmlScope != null)
{
XElement xmlElem = xmlScope.Element(value.Name);
if (xmlElem == null) xmlScope.Add(new XElement(value.Name, serialized));
else xmlElem.ReplaceAll(serialized);
}
else
{
xmlSettingsLoc.Add(new XElement(scope, new XElement(value.Name, serialized)));
}
}
}
}
在表单上创建一些控件(它们将对应于步骤1中的应用程序设置。)
我有:
文本框。名称:txtFullName
文本框。名称:txtSchool文本框:名称:txtClass
按钮:名称:btnLoadSettings文本:Load Config
按钮:名称:btnSaveSettings文本:保存配置
7。设置第一个按钮单击事件的代码。
private void btnLoadSettings_Click(object sender, EventArgs e) { txtName.Text = Properties.Settings.Default.Name.ToString(); txtSchool.Text = Properties.Settings.Default.School.ToString(); txtClass.Text = Properties.Settings.Default.Class.ToString(); }
8b。设置第二个按钮单击事件的代码。
private void btnSaveSettings_Click(object sender, EventArgs e) { Properties.Settings.Default.Name = txtName.Text; Properties.Settings.Default.School = txtSchool.Text; Properties.Settings.Default.Class = txtClass.Text; Properties.Settings.Default.Save(); }
- 就是这样。运行应用程序。使用第一个按钮加载设置)。对控件上的文本进行一些更改。使用第二个按钮保存它们。
在您的应用文件夹中,应该有一个新文件:Portable.config我的位于:C:\ Users \ flakie \ source \ repos \ TestApp \ TestApp \ bin \ Debug
您可以在txt / xml编辑器中打开文件以验证是否已设置值。
如果再次运行该应用程序并加载设置,则应该看到新值。