如何在Windows窗体应用程序中保存应用程序设置?

我想要实现的很是简单:我有一个Windows Forms(.NET 3.5)应用程序,该应用程序使用读取信息的路径。 用户可使用我提供的选项表单来修改此路径。 git

如今,我想将路径值保存到文件中以备后用。 这将是保存到该文件的众多设置之一。 该文件将直接位于应用程序文件夹中。 github

我了解三个选项可供选择: web

  • ConfigurationSettings文件(appname.exe.config)
  • 登记处
  • 自定义XML文件

我读到没有预见到.NET配置文件来将值保存回它。 至于注册表,我想尽量地远离它。 数据库

这是否意味着我应该使用自定义XML文件保存配置设置? 若是是这样,我想查看该代码示例(C#)。 app

我已经看到了有关该主题的其余讨论,可是对我来讲仍然不清楚。 this


#1楼

我不喜欢使用web.configapp.config的建议解决方案。 尝试读取您本身的XML。 看看XML设置文件-再也不须要web.config了编码


#2楼

有时您想要摆脱保留在传统web.config或app.config文件中的那些设置。 您但愿对设置条目和单独的数据设计的部署进行更精细的控制。 或要求是容许在运行时添加新条目。 spa

我能够想象两个不错的选择: 设计

  • 强类型版本和
  • 面向对象的版本。

强类型版本的优势是强类型设置名称和值。 不会混淆名称或数据类型。 缺点是必须对更多设置进行编码,不能在运行时添加。 code

使用面向对象的版本的优势是能够在运行时添加新设置。 可是您没有强类型的名称和值。 必须当心使用字符串标识符。 获取值时必须知道较早保存的数据类型。

您能够在此处找到这两种功能齐全的实现的代码。


#3楼

除了使用自定义XML文件之外,咱们还可使用其余更友好的文件格式:JSON或YAML文件。

  • 若是您使用.NET 4.0 dynamic,那么此库确实很是易于使用(序列化,反序列化,嵌套对象支持和按需排序输出顺序+将多个设置合并为一个) JsonConfig (用法等效于ApplicationSettingsBase)
  • 对于.NET YAML配置库...我尚未找到一个像JsonConfig同样易于使用的库

您能够将设置文件存储在此处列出的多个特殊文件夹(针对全部用户和每一个用户) Environment.SpecialFolder枚举和多个文件(默认只读,针对每一个角色,针对每一个用户等)

若是选择使用多个设置,则能够合并这些设置:例如,合并默认+ BasicUser + AdminUser的设置。 您可使用本身的规则:最后一个覆盖值,依此类推。


#4楼

一种简单的方法是使用配置数据对象,将其与应用程序的名称一块儿另存为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();
        }
    }
}

如今,您能够建立一个实例,并在表单的load和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>

#5楼

我想分享我为此创建的图书馆。 这是一个很小的库,可是相对于.settings文件有很大的改进(IMHO)。

该库名为Jot(GitHub) ,这是我写过的有关代码项目的旧文章

使用它来跟踪窗口的大小和位置的方法以下:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

与.settings文件相比 ,它的好处是:代码少得多,并且出错率也少得多,由于您只需说起每一个属性一次

对于设置文件,您须要五次说起每一个属性:一次是在您显式建立该属性时,另外一次是在代码中四次来回复制值。

存储,序列化等都是彻底可配置的。 当目标对象是由IOC容器建立的时,您能够[将其链接] [],以便它自动将跟踪应用于它解析的全部对象,以便对属性进行持久化处理所须要作的就是拍打[Trackable]属性在上面。

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

相信我,图书馆是一流的!

相关文章
相关标签/搜索