在较早时期,我写过一篇文章《结合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); }
最终,咱们在数据库表里面,能够看到对应记录已经保存起来了,而且用户密码部分也进行了加密处理。
这样,咱们整合二者的特色,就能够实现比较不错的参数配置界面的显示和后台存储处理了,针对性的,使用不一样的存储介质,以知足不一样的须要。