在較早時期,我寫過一篇文章《結合Control.FirefoxDialog控件,構造優秀的參數配置管理模塊》,介紹過在個人Winform框架基礎上集成的參數配置模塊功能,可是參數模塊的配置管理感受還不夠靈活,因而一直在尋找一個較好的替代者,用來結合FireFoxDialog界面一併展示,期間仔細研讀過好幾篇Codeproject網站上的關於配置管理的文章,可是老是以爲不夠靈活或者簡便。本文主要針對結合FireFoxDialog參數配置界面組件和SettingsProvider.net技術,實現較爲美觀、靈活的Winform程序參數配置管理。html
在CodeProject上有兩三篇文章介紹配置文件的很不錯,下面給出連接你們分享下:git
http://www.codeproject.com/Articles/25829/User-Settings-Appliedgithub
http://www.codeproject.com/Articles/475498/Easier-NET-settings數據庫
這兩個都很不錯,不過感受不太知足個人簡單、高效的需求,偶然之間在GitHub上發現一個《SettingsProvider.net》,作的很是不錯,並且感受擴展性也作的很好,所以就把它和FireFoxDialog界面一同整合,在框架內部實現參數管理功能。設計模式
這個是在GitHub上的一款參數配置組件,可以基於普通配置文件、ProgramData目錄文件、獨立存儲區文件等方式的配置文件存儲,它主要是基於Json格式進行的配置保存,所以咱們還能夠把它存儲到數據庫,雖然官方沒有提供例子,可是咱們很容易經過擴展實現這個功能,後面我介紹我對其數據庫參數保存擴展類。服務器
它還能夠經過Atrribute標識進行管理配置文件,能夠把參數設置爲加密、默認值、修更名稱等,以下是它的一個配置參數的類的例子。框架
public class MySettings { [DefaultValue("Jake")] [DisplayName("Your Name")] public string Name { get; set; } [DefaultValue(true)] [Description("Should Some App Remember your name?")] public bool RememberMe { get;set; } public List<Guid> Favourites { get;set; } [Key("OriginalName")] public string Renamed { get; set; } [ProtectedString] public string Encrypted { get; set; } }
讀取操做以下所示:ide
var settingsProvider = new SettingsProvider(); //By default uses IsolatedStorage for storage var mySettings = settingsProvider.GetSettings<MySettings>(); Assert.True(mySettings.RememberMe);
保存操做以下所示:post
var settingsProvider = new SettingsProvider(); //By default uses IsolatedStorage for storage var mySettings = new MySettings { Name = "Mr Ginnivan" }; settingsProvider.Save(mySettings);
參數元數據獲取操做代碼以下:網站
var settingsProvider = new SettingsProvider(); foreach (var setting in settingsProvider.ReadSettingMetadata<MySettings>()) { Console.WriteLine("{0} ({1}) - {2}", setting.DisplayName, setting.Description, setting.DefaultValue); }
基於上述的SettingsProvider.net的組件,咱們能夠結合我前面介紹的FireFoxDialog界面效果,實現較好的參數配置管理功能,以下界面所示。
咱們能夠分別把不一樣的參數放到不一樣的存儲介質裏面去,如一些經常使用的,能夠配置到本地目錄文件裏面去,一些和我的信息相關的內容,咱們能夠把它放到數據庫裏面去,這樣能夠在各個客戶端使用都不須要從新配置,很是方便。
上面的例子,我針對性介紹兩個,一個是基於本地文件參數存儲,一個是基於數據庫文件的參數存儲。
介紹了基於SettingsProvider.net的功能,以及最終整合的效果,咱們來看看它具體是如何整合實現不一樣文件類型數據的保存的。
首先,咱們在設計模式下,拖動好對應的界面,因爲FireFoxDialog界面原本就是用來作參數設置的,所以他們裏面有一些控件就不一一介紹了,具體能夠參考對應的文章(http://www.codeproject.com/KB/miscctrl/ControlFirefoxDialog.aspx?msg=1856449)。
咱們看看上述效果界面的設計界面和後臺代碼。
設計界面就是以下所示,拖動一個參數配置用戶控件到窗體上,設置好對應的內容就能夠了。
後臺代碼以下所示。
public partial class FrmSettings : BaseForm { public FrmSettings() { InitializeComponent(); } private void FrmSettings_Load(object sender, EventArgs e) { this.firefoxDialog1.ImageList = this.imageList1; this.firefoxDialog1.AddPage("報表設置", new PageReport());//基於本地文件的參數存儲 this.firefoxDialog1.AddPage("郵箱設置", new PageEmail());//基於數據庫的參數存儲 //下面是襯托的 this.firefoxDialog1.AddPage("短信設置", new PageEmail()); this.firefoxDialog1.AddPage("聲音設置", new PageEmail()); this.firefoxDialog1.AddPage("系統設置", new PageEmail()); this.firefoxDialog1.AddPage("備份設置", new PageEmail()); this.firefoxDialog1.AddPage("其餘設置", new PageEmail()); this.firefoxDialog1.Init(); } }
這裏最有表明性的是PageReport和PageEmail兩個組件對象。
基於報表參數和郵件參數,咱們能夠定義一個參數對象類,用來方便保存和獲取數據的承載對象。
報表參數對象類以下(只作了簡單的一個報表路徑處理):
/// <summary> /// 報表設置 /// </summary> public class ReportParameter { /// <summary> /// 派車單報表文件 /// </summary> [DefaultValue("WHC.CarDispatch.CarSendBill2.rdlc")] public string CarSendReportFile { get; set; } }
對應的設計界面以下所示,用來提供一個報表文件的參數配置,很簡單了。
咱們來看看後臺的組件,對參數是如何保存和顯示的。
首先須要初始化相應的對象,咱們這裏使用了在程序運行目錄下,建立一個文件用來保存這些設置。
public partial class PageReport : PropertyPage { private SettingsProvider settings; private ISettingsStorage store; public PageReport() { InitializeComponent(); if(!this.DesignMode) { // PortableStorage: 在運行程序目錄建立一個setting的文件記錄參數數據 store = new PortableStorage(); settings = new SettingsProvider(store); } }
注意:PortableStorage是在運行程序目錄建立一個setting的文件記錄參數數據,運行後,最終會在目錄下生成一個相似「ReportParameter.settings」的文件,它的內容格式以下所示。
[{"Key":"CarSendReportFile","Value":"\"WHC.CarDispatch.CarSendBill2.rdlc\""}]
咱們看看報表組件的參數是如何初始化的:
public override void OnInit() { ReportParameter parameter = settings.GetSettings<ReportParameter>(); if (parameter != null) { EnableOtherReport(false); string reportFile = parameter.CarSendReportFile; if (reportFile == "WHC.CarDispatch.CarSendBill2.rdlc") { this.radReport.SelectedIndex = 0; } else if (reportFile == "WHC.CarDispatch.CarSendBill.rdlc") { this.radReport.SelectedIndex = 1; } else { EnableOtherReport(true); this.radReport.SelectedIndex = 2; this.txtOtherReport.Text = reportFile; } } }
經過參數的存儲對象處理,這樣咱們就能夠經過ReportParameter 進行數據獲取了。
保存參數的時候,一樣也是先獲取到一個參數對象,並設置它的值後,而後進行保存就能夠了,具體代碼以下所示。
public override bool OnApply() { bool result = false; try { ReportParameter parameter = settings.GetSettings<ReportParameter>(); if (parameter != null) { int otherType = 2;//2表明其餘類型 if (this.radReport.SelectedIndex < otherType) { parameter.CarSendReportFile = this.radReport.Properties.Items[this.radReport.SelectedIndex].Value.ToString(); } else { parameter.CarSendReportFile = this.txtOtherReport.Text; } settings.SaveSettings<ReportParameter>(parameter); } result = true; } catch (Exception ex) { LogTextHelper.Error(ex); MessageDxUtil.ShowError(ex.Message); } return result; }
郵件參數對象類以下:
/// <summary> /// 郵箱設置 /// </summary> public class EmailParameter { /// <summary> /// 郵件帳號 /// </summary> //[DefaultValue("wuhuacong@163.com")] public string Email { get; set; } /// <summary> /// POP3服務器 /// </summary> [DefaultValue("pop.163.com")] public string Pop3Server { get; set; } /// <summary> /// POP3端口 /// </summary> [DefaultValue(110)] public int Pop3Port { get; set; } /// <summary> /// SMTP服務器 /// </summary> [DefaultValue("smtp.163.com")] public string SmtpServer { get; set; } /// <summary> /// SMTP端口 /// </summary> [DefaultValue(25)] public int SmtpPort { get; set; } /// <summary> /// 登錄帳號 /// </summary> public string LoginId { get; set; } /// <summary> /// 登錄密碼 /// </summary> [ProtectedString] public string Password { get; set; } /// <summary> /// 使用SSL加密 /// </summary> [DefaultValue(false)] public bool UseSSL { get; set; } }
參數顯示和保存的界面設計以下所示。
界面的初始化,一樣和上面的差很少,不過這裏使用了數據庫的存儲類DatabaseStorage,內容將保存在數據庫裏面,並且咱們經過用戶的標識Create進行路徑的針對性處理,可使每一個用戶的配置文件不一樣。
public partial class PageEmail : PropertyPage { private SettingsProvider settings; private ISettingsStorage store; public PageEmail() { InitializeComponent(); if (!this.DesignMode) { //DatabaseStorage:在數據庫裏面,以指定用戶標識保存參數數據 string creator = Portal.gc.LoginUserInfo.Name; store = new DatabaseStorage(creator); settings = new SettingsProvider(store); } }
參數的加載代碼以下所示,也就是把數據獲取後,顯示在界面上便可。
public override void OnInit() { EmailParameter parameter = settings.GetSettings<EmailParameter>(); if (parameter != null) { this.txtEmail.Text = parameter.Email; this.txtLoginId.Text = parameter.LoginId; this.txtPassword.Text = parameter.Password; this.txtPassword.Tag = parameter.Password; this.txtPop3Port.Value = parameter.Pop3Port; this.txtPop3Server.Text = parameter.Pop3Server; this.txtSmtpPort.Value = parameter.SmtpPort; this.txtSmtpServer.Text = parameter.SmtpServer; this.txtUseSSL.Checked = parameter.UseSSL; } }
數據的保存操做也很簡單,和前面的操做差很少,以下所示。
EmailParameter parameter = settings.GetSettings<EmailParameter>(); if (parameter != null) { parameter.Email = this.txtEmail.Text; parameter.LoginId = this.txtLoginId.Text; parameter.Password = this.txtPassword.Text; parameter.Pop3Port = Convert.ToInt32(this.txtPop3Port.Value); parameter.Pop3Server = this.txtPop3Server.Text; parameter.SmtpPort = Convert.ToInt32(this.txtSmtpPort.Value); parameter.SmtpServer = this.txtSmtpServer.Text; parameter.UseSSL = this.txtUseSSL.Checked; settings.SaveSettings<EmailParameter>(parameter); }
最終,咱們在數據庫表裏面,能夠看到對應記錄已經保存起來了,而且用戶密碼部分也進行了加密處理。
這樣,咱們整合二者的特色,就能夠實現比較不錯的參數配置界面的顯示和後臺存儲處理了,針對性的,使用不一樣的存儲介質,以知足不一樣的須要。