如何在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]屬性在上面。

它是高度可配置的,您能夠配置:-當數據持久保存並應用於全局或針對每一個跟蹤的對象時-序列化的方式-存儲的位置(例如文件,數據庫,在線,獨立存儲,註冊表)-能夠取消應用/持久化的規則屬性數據

相信我,圖書館是一流的!

相關文章
相關標籤/搜索