PropertyGrid中的属性读取

  • Post author:
  • Post category:其他




Load备份方法

 public class BaseSettings
    {
    	private Dictionary<string, int> intValues = null;
        private Dictionary<string, string> strValues = null;
        private Dictionary<string, bool> boolValues = null;
        private Dictionary<string, double> doubleValues = null;
        private DataSet ds = null;
        public static bool TipEnable = true;
        private const string intTableName = "IntTable";
        private const string stringTableName = "StringTable";
        private const string boolTableName = "BoolTable";
        private const string doubleTableName = "DoubleTable";
        private const string firstFieldName = "ParaName";
        private const string secondFieldName = "ParaValue";

		public string Name { get; private set; }
		//SettingFileName is a file whose extension is .xml
		private string SettingFileName
        {
            get
            {
                string asmFile = this.GetType().Assembly.Location;
                string asmPath = Path.GetDirectoryName(asmFile);
                if (string.Compare(Name, "Settings") == 0)
                {
                    return Path.ChangeExtension(asmFile, ".xml");
                }
                else
                {
                    return Path.Combine(asmPath, string.Format("{0}.xml", Name));
                }
            }
        }
		
		public BaseSettings(string settingName)
        {
            intValues = new Dictionary<string, int>();
            strValues = new Dictionary<string, string>();
            boolValues = new Dictionary<string, bool>();
            doubleValues = new Dictionary<string, double>();
            Name = settingName;
            SetupDataset();
            //因为我下方写了一个load的虚方法,这里执行this.load意为子类会重写一个load的方法
            this.Load();
        }
        //build up a DataSet ——— the introduction of DataSet are below the code
        //build up four DataTable,which are int,double,bool,string
        private void SetupDataset()
        {
            ds = new DataSet(Name);
            
            DataTable tbInt = new DataTable(intTableName);
            tbInt.Columns.Add(new DataColumn(firstFieldName, typeof(string)));
            tbInt.Columns.Add(new DataColumn(secondFieldName, typeof(int)));
            ds.Tables.Add(tbInt);

            DataTable tbString = new DataTable(stringTableName);
            tbString.Columns.Add(new DataColumn(firstFieldName, typeof(string)));
            tbString.Columns.Add(new DataColumn(secondFieldName, typeof(string)));
            ds.Tables.Add(tbString);

            DataTable tbBool = new DataTable(boolTableName);
            tbBool.Columns.Add(new DataColumn(firstFieldName, typeof(string)));
            tbBool.Columns.Add(new DataColumn(secondFieldName, typeof(bool)));
            ds.Tables.Add(tbBool);

            DataTable tbDouble = new DataTable(doubleTableName);
            tbDouble.Columns.Add(new DataColumn(firstFieldName, typeof(string)));
            tbDouble.Columns.Add(new DataColumn(secondFieldName, typeof(double)));
            ds.Tables.Add(tbDouble);

            // Set primary key for each table
            foreach (DataTable tb in ds.Tables)
            {
                DataColumn col = tb.Columns[0];
                tb.PrimaryKey = new DataColumn[] { col };

                tb.Columns[1].AllowDBNull = false;
            }
        }

		public virtual bool Load()
        {
            return Load(SettingFileName);
        }
        
        public virtual bool Load(string filePath)
        {
        	string gZipFile = Path.ChangeExtension(filePath, ".setting");
            if (File.Exists(gZipFile))
            {
                MemoryStream ms = new MemoryStream();
                try
                {
                    FileStream fs = File.OpenRead(gZipFile);
                    DecompressStream(fs, ms);
                    fs.Dispose();
                    fs.Close();
                }
                catch (Exception ex)
                {
                    SetupDataset();
                    Log(ex);
                    return false;
                }
                DataSet dsTmp = new DataSet();
                try
                {
                    ms.Position = 0;
                    dsTmp.ReadXml(ms, XmlReadMode.ReadSchema);
                }
                catch (Exception ex)
                {
                    SetupDataset();
                    Log(ex);
                    return false;
                }
                //合并两个dataSet
                ds.Merge(dsTmp);
                UpdateFromDatabase();
                return SettingsToProperties(this, this);
            }

            if (File.Exists(filePath))
            {
                DataSet dsTmp = new DataSet();
                try
                {
                    dsTmp.ReadXml(filePath, XmlReadMode.ReadSchema);
                }
                catch (Exception ex)
                {
                    SetupDataset();
                    Log(ex);
                    return false;
                }
                //合并两个dataSet
                ds.Merge(dsTmp);
                UpdateFromDatabase();
                return SettingsToProperties(this, this);
            }
            return false;
        }
        //write the contents of src to dst
        private void DecompressStream(Stream src, Stream dst)
        {
            byte[] buffer = new byte[4096];
            using (GZipStream input = new GZipStream(src, CompressionMode.Decompress, true))
            {
                int readBytes = 0;
                while ((readBytes = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    dst.Write(buffer, 0, readBytes);
                }
            }
        }
        
		//作用: 将dataSet里的数据同步到4个Dictionary里
        public void UpdateFromDatabase()
        {
            DataTable tb = null;
            tb = ds.Tables[intTableName];
            foreach (DataRow row in tb.Rows)
            {
                string Name = row[0] as string;
                if (string.IsNullOrEmpty(Name)) continue;
                int Value = (int)row[1];
                if (!intValues.ContainsKey(Name)) intValues.Add(Name, Value);
                else intValues[Name] = Value;
            }
            
            tb = ds.Tables[stringTableName];
            foreach (DataRow row in tb.Rows)
            {
                string Name = row[0] as string;
                if (string.IsNullOrEmpty(Name)) continue;
                string Value = row[1] as string;
                if (!strValues.ContainsKey(Name)) strValues.Add(Name, Value);
                else strValues[Name] = Value;
            }

            tb = ds.Tables[boolTableName];
            foreach (DataRow row in tb.Rows)
            {
                string Name = row[0] as string;
                if (string.IsNullOrEmpty(Name)) continue;
                bool Value = (bool)row[1];
                if (!boolValues.ContainsKey(Name)) boolValues.Add(Name, Value);
                else boolValues[Name] = Value;
            }

            tb = ds.Tables[doubleTableName];
            foreach (DataRow row in tb.Rows)
            {
                string Name = row[0] as string;
                if (string.IsNullOrEmpty(Name)) continue;
                double Value = (double)row[1];
                if (!doubleValues.ContainsKey(Name)) doubleValues.Add(Name, Value);
                else doubleValues[Name] = Value;
            }
        }
		//将参数读到属性中
		public static bool SettingsToProperties(BaseSettings settings, object obj)
        {
            int res = 1;
            Parallel.ForEach<PropertyInfo>(GetConfigProperties(obj), pi =>
            {
                if (!SettingToProperty(settings, string.Empty, obj, pi))
                {
                    if (res == 1) Interlocked.Exchange(ref res, 0);
                }
            });
            return res == 1;
        }
        //获取obj里面的所有特性属性
        public static List<PropertyInfo> GetConfigProperties(object obj)
        {
            List<PropertyInfo> pis = new List<PropertyInfo>();
            Type tp = typeof(Config);
            foreach (PropertyInfo pi in obj.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (pi.IsDefined(tp, true))
                {
                    pis.Add(pi);
                }
            }
            foreach (PropertyInfo pi in obj.GetType().GetProperties())
            {
                if (pi.IsDefined(tp, true))
                {
                    pis.Add(pi);
                }
            }
            return pis;
        }
        //将pi这个属性的值在setting中的值更新到pi中
        public static bool SettingToProperty(BaseSettings settings, string parentName, object obj, PropertyInfo pi)
        {
            if (settings == null) return false;
            if (!pi.CanWrite) return false;

            string name = string.Format("{0}{1}", parentName, pi.Name);
            if (pi.PropertyType == typeof(int))
            {
                int? val = settings.GetIntValue(name);
                if (val.HasValue)
                {
                    pi.SetValue(obj, val.Value, null);
                    return true;
                }
            }
            else if (pi.PropertyType == typeof(double))
            {
                double? val = settings.GetDoubleValue(name);
                if (val.HasValue)
                {
                    pi.SetValue(obj, val.Value, null);
                    return true;
                }
            }
            else if (pi.PropertyType == typeof(string))
            {
                string val = settings.GetStringValue(name);
                if (!string.IsNullOrEmpty(val))
                {
                    pi.SetValue(obj, val, null);
                    return true;
                }
            }
            else if (pi.PropertyType == typeof(bool))
            {
                bool? val = settings.GetBoolValue(name);
                if (val.HasValue)
                {
                    pi.SetValue(obj, val.Value, null);
                    return true;
                }
            }
            return false;
        }
        
        //在对应列表中找paraName的
        public int? GetIntValue(string paraName)
        {
            if (intValues.ContainsKey(paraName)) return intValues[paraName];
            else return null;
        }
        public double? GetDoubleValue(string paraName)
        {
            if (doubleValues.ContainsKey(paraName)) return doubleValues[paraName];
            else return null;
        }
        public string GetStringValue(string paraName)
        {
            if (strValues.ContainsKey(paraName)) return strValues[paraName];
            else return null;
        }
        public bool? GetBoolValue(string paraName)
        {
            if (boolValues.ContainsKey(paraName)) return boolValues[paraName];
            else return null;
        }
        
    }

DataSet类是ADO.NET中最核心的成员之一(ADO.NET是.Net Framework SDK中用以操作数据库的总称)。DataSet可以看作是一个数据容器,从数据库总抽取的数据可以存放在DataSet里面,也就相当与一个缓存区。

各种.net开发平台开发语言开发数据库应用程序,一般都不会直接对数据库进行操作,而是先完成

数据连接



通过数据适配器填充DataSet的对象

,然后客户端在通过读取DataSet来获取数据;相反也是一样,若是更新数据,是先对DataSet进行更新,最后同步DataSet和数据库。


DataSet有三大特性:

  • 独立性
  • 离线性
  • DataSet对象可用XML表示的数据视图(是一种关系视图)


DataSet结构:


DataSet——DataTable——row colunm



Load过程解析

  • 创建4个字典,用于存放4个不同类型的数据:intValues、strValues、boolValues、doubleValues

  • 通过属性获取SettingFileName:返回的是一个该文件目录下的.xml文件

  • 创建DataSet作为数据传送的中间缓存区,DataSet里创建了4个dataTable

    在这里插入图片描述

  • 开始读取xml配置文件内容:

    文件形式可能有两种 1、以.setting为后缀名的配置文件 2、以.xml为后缀名的配置文件。

    如果是setting文件就需要比.xml多一个解压步骤,就是利用GZipStream流将内容写入到MemoryStream流中。再利用DataSet.readxml()来将MemoryStream中的内容读取到DataSet中。

  • 将DataSet中的数据同步到4个字典里

    遍历所有dataTable里的所有内容,将其赋值到字典里,假若字典里没有的,便添加键值对

  • 通过反射获取属性,在将数据传入其中

    首先需要通过obj.GetType()获取obj里面的所有属性,返回list<PropertyInfo>

    再遍历获取到的属性类型,在对应的dataTable里找到其对应的值

    最后用.SetValue方法来设定方法的值



版权声明:本文为weixin_39292090原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。