快速准确的操作WPF应用程系的配置文件

时间:2024-06-01 21:04:38

废话不多说,先来看一个一个正常的WPF应用程系的配置是什么样的鬼

快速准确的操作WPF应用程系的配置文件

通常我们经常使用 的是ConnectionString (应用程系的数据库连接配置) 和 AppSettings(应用程系的配置)

特别注意的是:ConnectionString 默认已经有两个配制项(不知道这样的说法准确不准确) 见图

快速准确的操作WPF应用程系的配置文件

红色框中的很显然我没有在配置文件中配置过。


下面进入我要说的主题:

     1.先看一下,我的配置文件的读取方法

         /// <summary>
        /// 获取置配的值,会有异常,有异常是返回null
        /// </summary>
        /// <param name="configName"></param>
        /// <returns></returns>
        public static string GetConfig(string configName)
        {
            try
            {
                return ConfigurationManager.AppSettings[configName];
            }
            catch (Exception)
            {
                return null;
            }

        }

         /// <summary>
        /// set the config item's value,if not Exist Auto Create,last save to config file
        /// </summary>
        /// <param name="configName"></param>
        /// <param name="value"></param>
        public static void SetConfig(string configName, string value)
        {
            Configuration cf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            bool exists = false;
            foreach (string key in cf.AppSettings.Settings.AllKeys)
            {
                if (key == configName)
                {
                    exists = true;
                    continue;
                }
            }
            if (exists)
            {
                cf.AppSettings.Settings[configName].Value = value;
            }
            else
            {
                cf.AppSettings.Settings.Add(configName, value);                
            }
            cf.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection(AppSettingsSectionName);
            // save config value to file
            svaeConfigValueToFile(configName, value);
        }

         /// <summary>
        /// 依据连接串名字connectionName返回数据连接字符串
        /// </summary>
        /// <param name="configName">依据连接串名字</param>
        /// <returns></returns>
        public static string GetConnectionConfig(string configName)
        {
            try
            {
                return ConfigurationManager.ConnectionStrings[configName].ConnectionString.ToString();
            }
            catch (Exception)
            {
                return null;
            }
        }


        ///<summary>
        ///更新连接字符串 如果没有则自动创建
        ///</summary>
        ///<param name="newName">连接字符串名称</param>
        ///<param name="newConString">连接字符串内容</param>
        public static void SetConnectionConfig(string configName, string value)
        {
            bool isExists = false;
            if (ConfigurationManager.ConnectionStrings[configName] != null)
            {
                isExists = true;
            }
            ConnectionStringSettings css = new ConnectionStringSettings(configName, value);
            Configuration cf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (isExists)
            {
                cf.ConnectionStrings.ConnectionStrings.Remove(configName);
            }
            cf.ConnectionStrings.ConnectionStrings.Add(css);
            cf.Save();
            ConfigurationManager.RefreshSection(ConnectionStringsSectionName);
            svaeConfigValueToFile(configName, value, "connectionStrings");
        }

      动态的配置,在配置文件里,肉眼是看不到,只有程序能认识,并且在下一次启动时,又要重先来动态的配置一次。

      下面提供个方法,让动态配置,直接在配置文件显示,下次启动不需要再配置。

       /// <summary>
        /// update config item's value and save it in configuation file
        /// </summary>
        /// <param name="configName"></param>
        /// <param name="value"></param>
        /// <param name="groupName">appSettings or connectionSettings </param>
        public static void svaeConfigValueToFile(string configName, string value, string groupName = "appSettings")
        {
            string configFileName = "App.config";
            string filePath = FileHelper.GetProjectRootPath() + "/" + configFileName;
            XmlDocument doc = new XmlDocument();
            doc.Load(filePath);
            XmlNode group = doc.DocumentElement.SelectSingleNode(groupName);
            if (group == null)
            {
                group = doc.CreateNode(XmlNodeType.Element, groupName, null);
                group.AppendChild(createXmlNode(doc, configName, value, groupName));
                doc.AppendChild(group);
            }
            bool isFind = false;
            foreach (XmlNode item in group.ChildNodes)
            {
                if (groupName == "connectionStrings")
                {
                    if (item.Attributes["name"].InnerText == configName)
                    {
                        item.Attributes["connectionString"].InnerText = value;
                        isFind = true;
                        continue;
                    }
                }
                else
                {
                    if (item.Attributes["key"].InnerText == configName)
                    {
                        item.Attributes["value"].InnerText = value;
                        isFind = true;
                        continue;
                    }
                }
            }
            if (isFind == false)
            {
                group.AppendChild(createXmlNode(doc, configName, value, groupName));               
            }
            doc.Save(filePath);
        }

        private static XmlNode createXmlNode(XmlDocument doc, string configName, string value, string groupName)
        {
            string name = "key";
            string valuetag = "value";
            if (groupName == "connectionStrings")
            {
                name = "name";
                value = "connectionString";
            }
            XmlNode node = doc.CreateElement("add") as XmlNode;
            XmlAttribute att = doc.CreateAttribute(name);
            att.InnerText = configName;
            XmlAttribute val = doc.CreateAttribute(valuetag);
            val.InnerText = value;
            node.Attributes.Append(att);
            node.Attributes.Append(val);
            return node;
        }

     

        2.再来看一下,这些个方法使用

        快速准确的操作WPF应用程系的配置文件

        3.如何快速和准确的操作呢

           我们知道配置项是字符串,IDE不会自动提示,而且我们很容易输错,经常性记不住有些什么样的配置项,我们想IDE自动提示来减少输入,和出错,帮助我们记忆,

          我是这样做的,新建一个ConfigItemName 的枚举,其中的每一项和配置项对应。如图

          快速准确的操作WPF应用程系的配置文件

这样就满足我们上面说的需求

4.如何我们还想在应用程系正试使用的环境中,我们也想看到动态配置。我们就要再用数据库来保存这些配置项,那什么时候保存到数据库,我建议是利用程序退出事件触发器,在程序退出前,把所有和配制项保存到数据中,利用数据库保存还有一个好处是我们切换电脑的时候,所有的配置可以快速迁移。

数据结构

快速准确的操作WPF应用程系的配置文件

代码


        /// <summary>
        /// save the config file's config Item to database
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Application_Exit(object sender, ExitEventArgs e)
        {
         ConnectionStringSettingsCollection conns =   ConfigurationManager.ConnectionStrings;
            DatabaseOPtionHelper helper=null;
            for (int i = 0; i < conns.Count; i++)
            {
                Config config = new Config();
                if (!conns[i].Name.Contains("Local")) {
                    if (!string.IsNullOrWhiteSpace(conns[i].ConnectionString.ToString())) {
                        config.clientId = ConfigurationHelper.GetConfig(ConfigItemName.clientId.ToString());
                        config.configName = conns[i].Name;
                        config.configValue = conns[i].ConnectionString;
                        config.syncTime = DateTimeHelper.ConvertDateTimeToInt(DateTime.Now);
                        if (helper == null) {
                            helper = new DatabaseOPtionHelper();
                        }
                        helper.insertOrUpdate(config);
                    }
                }              
            }

            NameValueCollection collection = ConfigurationManager.AppSettings;
            string[] keys = collection.AllKeys;
            foreach (string key in keys)
            {
                if (!string.IsNullOrWhiteSpace(collection[key])){
                    Config config = new Config();
                    config.clientId = ConfigurationHelper.GetConfig(ConfigItemName.clientId.ToString());
                    config.configName =key;
                    config.configValue = collection[key];
                    config.syncTime = DateTimeHelper.ConvertDateTimeToInt(DateTime.Now);
                    if (helper == null)
                    {
                        helper = new DatabaseOPtionHelper();
                    }
                    helper.insertOrUpdate(config);
                }               
            }
        }

代码不是很完善,因为每一条数据都要去走一次数据库的操作流程,如果朋友们有时间,可以改进一下,尽量只走一次数据的操作流程就把所有数据保存。


如果有不当的地方请原谅和指出。