C# 字典项=新字典(); Type Type=src.GetType(); 字符串[]paramList=target.Split(新字符[]{',}); foreach(paramList中的字符串paramName) Add(paramName,type.GetProperty(paramName.Trim()).GetValue(src,null)); 尝试 { //GetUserStoreForApplication不工作-无法识别。 //应用程序,除非由ClickOnce或Silverlight发布 IsolatedStorageFile storage=IsolatedStorageFile.GetUserStoreForAssembly(); 使用(IsolatedStorageFileStream=新的IsolatedStorageFileStream(文件名,FileMode.Create,storage)) 使用(StreamWriter=新StreamWriter(流)) { Write((新的JavaScriptSerializer()).Serialize(items)); } } catch(Exception){}//If失败-只是不使用首选项 } 内部静态无效加载(对象tar、字符串文件名) { 字典项=新字典(); Type=tar.GetType(); 尝试 { //GetUserStoreForApplication不工作-无法识别 //应用程序,除非由ClickOnce或Silverlight发布 IsolatedStorageFile storage=IsolatedStorageFile.GetUserStoreForAssembly(); 使用(IsolatedStorageFileStream=新的IsolatedStorageFileStream(文件名,FileMode.Open,存储)) 使用(StreamReader=新StreamReader(stream)) { items=(新的JavaScriptSerializer()); } } catch(Exception){return;}//如果失败,只需不使用首选项即可。 foreach(项中的KeyValuePair对象) { 尝试 { tar.GetType().GetProperty(obj.Key).SetValue(tar,obj.Value,null); } 捕获(异常){} } } }

C# 字典项=新字典(); Type Type=src.GetType(); 字符串[]paramList=target.Split(新字符[]{',}); foreach(paramList中的字符串paramName) Add(paramName,type.GetProperty(paramName.Trim()).GetValue(src,null)); 尝试 { //GetUserStoreForApplication不工作-无法识别。 //应用程序,除非由ClickOnce或Silverlight发布 IsolatedStorageFile storage=IsolatedStorageFile.GetUserStoreForAssembly(); 使用(IsolatedStorageFileStream=新的IsolatedStorageFileStream(文件名,FileMode.Create,storage)) 使用(StreamWriter=新StreamWriter(流)) { Write((新的JavaScriptSerializer()).Serialize(items)); } } catch(Exception){}//If失败-只是不使用首选项 } 内部静态无效加载(对象tar、字符串文件名) { 字典项=新字典(); Type=tar.GetType(); 尝试 { //GetUserStoreForApplication不工作-无法识别 //应用程序,除非由ClickOnce或Silverlight发布 IsolatedStorageFile storage=IsolatedStorageFile.GetUserStoreForAssembly(); 使用(IsolatedStorageFileStream=新的IsolatedStorageFileStream(文件名,FileMode.Open,存储)) 使用(StreamReader=新StreamReader(stream)) { items=(新的JavaScriptSerializer()); } } catch(Exception){return;}//如果失败,只需不使用首选项即可。 foreach(项中的KeyValuePair对象) { 尝试 { tar.GetType().GetProperty(obj.Key).SetValue(tar,obj.Value,null); } 捕获(异常){} } } },c#,xml,winforms,configuration-files,application-settings,C#,Xml,Winforms,Configuration Files,Application Settings,有时,您希望删除传统web.config或app.config文件中保留的设置。您希望对设置项和分离数据设计的部署进行更细粒度的控制。或者要求能够在运行时添加新条目 我可以想象两个好的选择: 强类型版本和 面向对象的版本 强类型版本的优点是强类型设置名称和值。没有混合名称或数据类型的风险。缺点是必须编码更多的设置,不能在运行时添加 使用面向对象的版本,优点是可以在运行时添加新设置。但是您没有强类型的名称和值。必须小心使用字符串标识符。获取值时必须知道先前保存的数据类型 您可以找到这两种全功能

有时,您希望删除传统web.config或app.config文件中保留的设置。您希望对设置项和分离数据设计的部署进行更细粒度的控制。或者要求能够在运行时添加新条目

我可以想象两个好的选择:

  • 强类型版本和
  • 面向对象的版本
强类型版本的优点是强类型设置名称和值。没有混合名称或数据类型的风险。缺点是必须编码更多的设置,不能在运行时添加

使用面向对象的版本,优点是可以在运行时添加新设置。但是您没有强类型的名称和值。必须小心使用字符串标识符。获取值时必须知道先前保存的数据类型


您可以找到这两种全功能实现的代码。

其他选项,而不是使用自定义XML文件,我们可以使用更用户友好的文件格式:JSON或YAML文件

  • 如果您使用.NET4.0Dynamic,这个库非常容易使用 (序列化、反序列化、嵌套对象支持和排序输出 如您所愿+将多个设置合并为一个(用法相当于ApplicationSettingsBase)
  • 对于.NET YAML配置库。。。我还没有找到一个像这样的 与JsonConfig一样易于使用
您可以将设置文件存储在此处列出的多个特殊文件夹(针对所有用户和每个用户)和多个文件(默认只读、每个角色、每个用户等)中

  • 获取特殊文件夹路径的示例:

如果选择使用多个设置,则可以合并这些设置:例如,合并default+BasicUser+AdminUser的设置。您可以使用自己的规则:最后一个规则覆盖值等。

一种简单的方法是使用配置数据对象,将其保存为XML文件,并在本地文件夹中包含应用程序的名称,然后在启动时将其读回

下面是一个存储表单位置和大小的示例

配置数据对象为强类型且易于使用:

[Serializable()]
public class CConfigDO
{
    private System.Drawing.Point m_oStartPos;
    private System.Drawing.Size m_oStartSize;

    public System.Drawing.Point StartPos
    {
        get { return m_oStartPos; }
        set { m_oStartPos = value; }
    }

    public System.Drawing.Size StartSize
    {
        get { return m_oStartSize; }
        set { m_oStartSize = value; }
    }
}
用于保存和加载的管理器类:

public class CConfigMng
{
    private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
    private CConfigDO m_oConfig = new CConfigDO();

    public CConfigDO Config
    {
        get { return m_oConfig; }
        set { m_oConfig = value; }
    }

    // Load configuration file
    public void LoadConfig()
    {
        if (System.IO.File.Exists(m_sConfigFileName))
        {
            System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
            Type tType = m_oConfig.GetType();
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            object oData = xsSerializer.Deserialize(srReader);
            m_oConfig = (CConfigDO)oData;
            srReader.Close();
        }
    }

    // Save configuration file
    public void SaveConfig()
    {
        System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
        Type tType = m_oConfig.GetType();
        if (tType.IsSerializable)
        {
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            xsSerializer.Serialize(swWriter, m_oConfig);
            swWriter.Close();
        }
    }
}
现在,您可以创建实例并在表单的加载和关闭事件中使用:

    private CConfigMng oConfigMng = new CConfigMng();

    private void Form1_Load(object sender, EventArgs e)
    {
        // Load configuration
        oConfigMng.LoadConfig();
        if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
        {
            Location = oConfigMng.Config.StartPos;
            Size = oConfigMng.Config.StartSize;
        }
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Save configuration
        oConfigMng.Config.StartPos = Location;
        oConfigMng.Config.StartSize = Size;
        oConfigMng.SaveConfig();
    }
生成的XML文件也是可读的:

<?xml version="1.0" encoding="utf-8"?>
<CConfigDO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <StartPos>
    <X>70</X>
    <Y>278</Y>
  </StartPos>
  <StartSize>
    <Width>253</Width>
    <Height>229</Height>
  </StartSize>
</CConfigDO>

70
278
253
229

我想分享一个为此而构建的库。这是一个很小的库,但比.settings文件有很大的改进(IMHO)

图书馆的名字叫。这是我写的一篇老文章

下面是如何使用它来跟踪窗口的大小和位置:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}
与.settings文件相比的优点:代码要少得多,而且容易出错,因为每个属性只需提及一次

对于设置文件,您需要提及每个属性五次:明确创建属性时提及一次,在来回复制值的代码中另外提及四次

存储、序列化等是完全可配置的。当目标对象由容器创建时,您可以[hook it up][],以便它自动将跟踪应用于它解析的所有对象,这样,使属性持久化所需做的就是在其上添加[Trackable]属性

它是高度可配置的,您可以配置: -当数据被全局或针对每个跟踪对象持久化和应用时 -它是如何序列化的 -存储位置(例如文件、数据库、在线、独立存储、注册表) -可以取消应用/持久化属性数据的规则

相信我,图书馆是一流的

公共静态类设置
public static class SettingsExtensions
{
    public static bool TryGetValue<T>(this Settings settings, string key, out T value)
    {
        if (settings.Properties[key] != null)
        {
            value = (T) settings[key];
            return true;
        }

        value = default(T);
        return false;
    }

    public static bool ContainsKey(this Settings settings, string key)
    {
        return settings.Properties[key] != null;
    }

    public static void SetValue<T>(this Settings settings, string key, T value)
    {
        if (settings.Properties[key] == null)
        {
            var p = new SettingsProperty(key)
            {
                PropertyType = typeof(T),
                Provider = settings.Providers["LocalFileSettingsProvider"],
                SerializeAs = SettingsSerializeAs.Xml
            };
            p.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
            var v = new SettingsPropertyValue(p);
            settings.Properties.Add(p);
            settings.Reload();
        }
        settings[key] = value;
        settings.Save();
    }
}
{ 公共静态bool TryGetValue(此设置、字符串键、输出T值) { if(settings.Properties[key]!=null) { 值=(T)设置[键]; 返回true; } 值=默认值
public class CConfigMng
{
    private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
    private CConfigDO m_oConfig = new CConfigDO();

    public CConfigDO Config
    {
        get { return m_oConfig; }
        set { m_oConfig = value; }
    }

    // Load configuration file
    public void LoadConfig()
    {
        if (System.IO.File.Exists(m_sConfigFileName))
        {
            System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
            Type tType = m_oConfig.GetType();
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            object oData = xsSerializer.Deserialize(srReader);
            m_oConfig = (CConfigDO)oData;
            srReader.Close();
        }
    }

    // Save configuration file
    public void SaveConfig()
    {
        System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
        Type tType = m_oConfig.GetType();
        if (tType.IsSerializable)
        {
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            xsSerializer.Serialize(swWriter, m_oConfig);
            swWriter.Close();
        }
    }
}
    private CConfigMng oConfigMng = new CConfigMng();

    private void Form1_Load(object sender, EventArgs e)
    {
        // Load configuration
        oConfigMng.LoadConfig();
        if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
        {
            Location = oConfigMng.Config.StartPos;
            Size = oConfigMng.Config.StartSize;
        }
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Save configuration
        oConfigMng.Config.StartPos = Location;
        oConfigMng.Config.StartSize = Size;
        oConfigMng.SaveConfig();
    }
<?xml version="1.0" encoding="utf-8"?>
<CConfigDO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <StartPos>
    <X>70</X>
    <Y>278</Y>
  </StartPos>
  <StartSize>
    <Width>253</Width>
    <Height>229</Height>
  </StartSize>
</CConfigDO>
public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}
public static class SettingsExtensions
{
    public static bool TryGetValue<T>(this Settings settings, string key, out T value)
    {
        if (settings.Properties[key] != null)
        {
            value = (T) settings[key];
            return true;
        }

        value = default(T);
        return false;
    }

    public static bool ContainsKey(this Settings settings, string key)
    {
        return settings.Properties[key] != null;
    }

    public static void SetValue<T>(this Settings settings, string key, T value)
    {
        if (settings.Properties[key] == null)
        {
            var p = new SettingsProperty(key)
            {
                PropertyType = typeof(T),
                Provider = settings.Providers["LocalFileSettingsProvider"],
                SerializeAs = SettingsSerializeAs.Xml
            };
            p.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
            var v = new SettingsPropertyValue(p);
            settings.Properties.Add(p);
            settings.Reload();
        }
        settings[key] = value;
        settings.Save();
    }
}
[General]
# a comment
SomeString = Hello World!
SomeInteger = 10 # an inline comment
var config = Configuration.LoadFromFile("sample.cfg");
var section = config["General"];

string someString = section["SomeString"].StringValue;
int someInteger = section["SomeInteger"].IntValue;