在较早时期,我写过一篇文章《结合Control.FirefoxDialog控件,构造优秀的参数配置管理模块》,介绍过在我的Winform框架基础上集成的参数配置模块功能,但是参数模块的配置管理感觉还不够灵活,于是一直在寻找一个较好的替代者,用来结合FireFoxDialog界面一并展现,期间仔细研读过好几篇Codeproject网站上的关于配置管理的文章,但是总是觉得不够灵活或者简便。本文主要针对结合FireFoxDialog参数配置界面组件和SettingsProvider.net技术,实现较为美观、灵活的Winform程序参数配置管理。

在CodeProject上有两三篇文章介绍配置文件的很不错,下面给出链接大家分享下:

http://www.codeproject.com/Articles/25829/User-Settings-Applied

http://www.codeproject.com/Articles/475498/Easier-NET-settings

这两个都很不错,不过感觉不太满足我的简单、高效的需求,偶然之间在GitHub上发现一个《SettingsProvider.net》,做的非常不错,而且感觉扩展性也做的很好,因此就把它和FireFoxDialog界面一同整合,在框架内部实现参数管理功能。

1、SettingsProvider.net功能介绍

这个是在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; }
}

读取操作如下所示:

var settingsProvider = new SettingsProvider(); //By default uses IsolatedStorage for storage
var mySettings = settingsProvider.GetSettings<MySettings>();
Assert.True(mySettings.RememberMe);

保存操作如下所示:

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);
}

2、参数配置功能界面截图

基于上述的SettingsProvider.net的组件,我们可以结合我前面介绍的FireFoxDialog界面效果,实现较好的参数配置管理功能,如下界面所示。

我们可以分别把不同的参数放到不同的存储介质里面去,如一些常用的,可以配置到本地目录文件里面去,一些和个人信息相关的内容,我们可以把它放到数据库里面去,这样可以在各个客户端使用都不需要重新配置,非常方便。

上面的例子,我针对性介绍两个,一个是基于本地文件参数存储,一个是基于数据库文件的参数存储。

3、基于SettingsProvider.net的整合操作的实现

介绍了基于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两个组件对象。

1)报表模块配置管理

基于报表参数和邮件参数,我们可以定义一个参数对象类,用来方便保存和获取数据的承载对象。

报表参数对象类如下(只做了简单的一个报表路径处理):

    /// <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 = ;
}
else if (reportFile == "WHC.CarDispatch.CarSendBill.rdlc")
{
this.radReport.SelectedIndex = ;
}
else
{
EnableOtherReport(true);
this.radReport.SelectedIndex = ;
this.txtOtherReport.Text = reportFile;
}
}
}

通过参数的存储对象处理,这样我们就可以通过ReportParameter 进行数据获取了。

保存参数的时候,同样也是先获取到一个参数对象,并设置它的值后,然后进行保存就可以了,具体代码如下所示。

        public override bool OnApply()
{
bool result = false;
try
{
ReportParameter parameter = settings.GetSettings<ReportParameter>();
if (parameter != null)
{
int otherType = ;//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;
}

2)邮件参数配置管理

邮件参数对象类如下:

    /// <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()]
public int Pop3Port { get; set; } /// <summary>
/// SMTP服务器
/// </summary>
[DefaultValue("smtp.163.com")]
public string SmtpServer { get; set; } /// <summary>
/// SMTP端口
/// </summary>
[DefaultValue()]
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);
}

最终,我们在数据库表里面,可以看到对应记录已经保存起来了,并且用户密码部分也进行了加密处理。

这样,我们整合两者的特点,就可以实现比较不错的参数配置界面的显示和后台存储处理了,针对性的,使用不同的存储介质,以满足不同的需要。

Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建的更多相关文章

  1. Winform开发框架之客户关系管理系统(CRM)的开发总结系列3-客户分类和配置管理实现

    我在本系列随笔的开始,介绍了CRM系统一个重要的客户分类的展示界面,其中包含了从字典中加载分类.从已有数据中加载分类.以及分组列表中加载分类等方式的实现,以及可以动态对这些节点进行配置,实现客户分类的 ...

  2. Winform开发框架之存储过程的支持--存储过程的实现和演化提炼(2)

    本篇继续上篇<Winform开发框架之存储过程的支持--存储过程的实现和演化提炼(1)>来对Winform开发框架之存储过程的支持进行介绍,上篇主要介绍了SQLServer和Oracle两 ...

  3. Winform开发框架之插件化应用框架实现

    支持插件化应用的开发框架能给程序带来无穷的生命力,也是目前很多系统.程序追求的重要方向之一,插件化的模块,在遵循一定的接口标准的基础上,可以实现快速集成,也就是所谓的热插拔操作,可以无限对已经开发好系 ...

  4. 如何基于Winform开发框架或混合框架基础上进行项目的快速开发

    在开发项目的时候,我们为了提高速度和质量,往往不是白手起家,需要基于一定的基础上进行项目的快速开发,这样可以利用整个框架的生态基础模块,以及成熟统一的开发方式,可以极大提高我们开发的效率.本篇随笔就是 ...

  5. 基于Enterprise Library的Winform开发框架实现支持国产达梦数据库的扩展操作

    由于一个客户朋友的需求,需要我的Winform开发框架支持国产达梦数据库的操作,这个数据库很早就听过,但是真正一般项目用的很少,一般在一些特殊的项目可能需要用到.由于我的Winform开发框架,是基于 ...

  6. Winform开发框架之客户关系管理系统(CRM)的开发总结系列1-界面功能展示

    一直以来,都希望整合一个以客户为中心的平台,有两个方面的考虑:一是实现客户数据.客户关系.客户管理等方面的整合,以便更好利用好客户的相关资源,发挥最大的营销效益:二是整合目前我的开发框架的所有模块和技 ...

  7. Winform开发框架中的内容及文档管理模块功能介绍

    在开发项目的时候,我们有一些场景需要编辑一些HTML文档,作为内容发布系统的一部分,有时候也需要对一些文档如WORD文档进行编辑管理,这样需要我们对这些内容及文档进行合适的管理.本文主要介绍在WInf ...

  8. Winform开发框架之权限管理系统功能介绍

    权限管理系统的重要特性总结: 1) 高度集成的权限系统.独立模块,能快速整合使用.2) 符合权限的国际通用标准,基于RBAC(基于角色的访问控制)的角色权限控制.3) 多数据库架构支持,内置支持Sql ...

  9. Winform开发框架的重要特性总结

    从事Winform开发框架的研究和推广,也做了有几个年头了,从最初的项目雏形到目前各种重要特性的加入完善,是经过了很多项目的总结归纳和升华,有些则是根据客户需要或者应用前景的需要进行的完善,整个Win ...

随机推荐

  1. 浅谈Excel开发:十 Excel 开发中与线程相关的若干问题

    采用VSTO或者Shared Add-in等技术开发Excel插件,其实是在与Excel提供的API在打交道,Excel本身的组件大多数都是COM组件,也就是说通过Excel PIA来与COM进行交互 ...

  2. [ACM_动态规划] 找零种类

    问题描述:假设某国的硬币的面值有 1.5.10.50 元四种,输入一个金额 N (正整数,N<=1000),印出符合该金额的硬币组合有多少种. 问题分析: 1.5.10 元组合出 N 元的方法数 ...

  3. 12小时包你学会基于ReactMix框架的ReactNativeApp开发(一)Hello World!

    ReactMixhttps://github.com/xueduany/react-mix自从昨天发布起来,得到了不少小伙伴的热捧,很高兴帮助大家解决了憋在心中很久的问题“如果我只会HTML,Css, ...

  4. linux下目录操作

    1. 常用函数 #include <dirent.h> //open a directory //failed-NULL, other-return a DIR stream DIR *o ...

  5. MVVM架构~Knockoutjs系列之对象与对象组合

    返回目录 在面向对象的程序设计里,对象是核心,一切皆为对象,对象与对象之间的关系可以表现为继承和组合,而在Knockoutjs或者JS里,也存在着对象的概念,今天主要说一下JS里的对象及对象的组合. ...

  6. EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!

    回到目录 Entityframeworks很聪明 不错,非常不错!ef里的contains比linq to sql里的contains有了明显的提升,事实上,是在进行SQL语句翻译上有所提升,在lin ...

  7. js笔记——call,apply,bind使用笔记

    call和apply obj.call(thisObj, arg1, arg2, ...); obj.apply(thisObj, [arg1, arg2, ...]); 两者作用一致,都是把obj( ...

  8. lua实现深度拷贝table表

    lua当变量作为函数的参数进行传递时,类似的也是boolean,string,number类型的变量进行值传递.而table,function,userdata类型的变量进行引用传递.故而当table ...

  9. [C#反射]C#中的反射解析及使用.

    1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 参考: C#反射,MSDN编程指南 反射是一个程序集发现及运行的过程,通过 ...

  10. Atitit 图片 验证码生成attilax总结

    Atitit 图片 验证码生成attilax总结 1.1. 图片验证码总结1 1.2. 镂空文字  打散 干扰线 文字扭曲 粘连2 1.1. 图片验证码总结 因此,CAPTCHA在图片验证码这一应用点 ...