如何将应用程序设置保存到其他位置和文件名

问题描述 投票:1回答:2

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文件?

我想做什么?

如果有人有任何说明和示例代码?

c# openfiledialog application-settings savefiledialog
2个回答
0
投票

使用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");  
    }  
} 

0
投票

更新。我已经安装了新的设置提供程序,并且正在工作。将XML保存到app文件夹。它可能支持多个配置文件(因为我支持更改文件名)。由于开发人员正在帮助我,我也正在测试PeanutButter ini。当/如果我能正常工作,我将在这里详细介绍。

以下是设置新的设置提供程序的说明:

  1. 设置应用程序设置(在解决方案资源管理器中,右键单击应用程序。然后选择:属性。然后打开:设置)。

在我的测试应用中,我的设置如下:

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
  1. 从NuGet安装新的设置提供程序(在解决方案资源管理器中,右键单击:引用。然后选择:管理NuGet软件包。然后搜索:PortableSettingsProvider。安装它。)]] >>

  2. 在Program.cs中,修改static void Main()

    。添加以下行:
  3. 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());
    }
    
  1. 仍然在Program.cs中,设置使用:

    我的外观如下所示(我不确定是否全部必要,但会在实际应用上线之前进行整理)。添加任何缺少的内容:

  2. 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;
    
  1. 仍然在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)));
                }
            }
        }
    }
    
  2. 在表单上创建一些控件(它们将对应于步骤1中的应用程序设置。)

  3. 我有:

    文本框。名称: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();
}
  1. 就是这样。运行应用程序。使用第一个按钮加载设置)。对控件上的文本进行一些更改。使用第二个按钮保存它们。

在您的应用文件夹中,应该有一个新文件:Portable.config我的位于:C:\ Users \ flakie \ source \ repos \ TestApp \ TestApp \ bin \ Debug

您可以在txt / xml编辑器中打开文件以验证是否已设置值。

如果再次运行该应用程序并加载设置,则应该看到新值。

© www.soinside.com 2019 - 2024. All rights reserved.