Winform開發框架之參數配置管理功能實現-基於SettingsProvider.net的構建


在較早時期,我寫過一篇文章《結合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 = 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;
        }

 

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

最終,我們在數據庫表里面,可以看到對應記錄已經保存起來了,並且用戶密碼部分也進行了加密處理。

這樣,我們整合兩者的特點,就可以實現比較不錯的參數配置界面的顯示和后台存儲處理了,針對性的,使用不同的存儲介質,以滿足不同的需要。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM