• C#通用的参数设置功能模块(ini文件配置)


    以下是学习笔记:

    1,参数设置的子窗体设置

    【1.1】大小要和主窗体嵌入的panel尺寸一致

    【2.2】字体和大小要一致

    【3.3】无边框设置FormBorderStyle.None

    2,批量参数设置思路

    Ini:

    Section 1个:参数

    Key 2个:基础参数,高级参数

    JSON:对象和JSON字符串之间的互相转换

    反射:控件Name就是对象属性的名称

    Tag: 参数修改记录

    3,代码实现步骤

    【3.1】帮助类,写在DAL中

    【3.1.1】INI帮助类

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace AutomaticStoreMotionDal
    {
        public class IniConfigHelper
        {
            #region 方法说明
    
            //WritePrivateProfileString方法说明:
    
            //功能:将信息写入ini文件
    
            //    返回值:long,如果为0则表示写入失败,反之成功。
    
            //参数1(section) :写入ini文件的某个小节名称(不区分大小写)。
    
            //参数2(key) :上面section下某个项的键名(不区分大小写)。
    
            //参数3(val) :上面key对应的value
    
            //参数4(filePath):ini的文件名,包括其路径(example: "c:/config.ini")。如果没有指定路径,仅有文件名,系统会自动在windows目录中查找是否有对应的ini文件,如果没有则会自动在当前应用程序运行的根目录下创建ini文件。
    
    
    
            //GetPrivateProfileString方法使用说明:
    
            //功能:从ini文件中读取相应信息
    
            //    返回值:返回所取信息字符串的字节长度
    
            //    参数1(section):某个小节名(不区分大小写),如果为空,则将在retVal内装载这个ini文件的所有小节列表。
    
            //参数2(key) :欲获取信息的某个键名(不区分大小写),如果为空,则将在retVal内装载指定小节下的所有键列表。
    
            //参数3(def) :当指定信息,未找到时,则返回def,可以为空。
    
            //参数4(retVal) :一个字串缓冲区,所要获取的字符串将被保存在其中,其缓冲区大小至少为size。
    
            //参数5(size) :retVal的缓冲区大小(最大字符数量)。
    
            //参数6(filePath) :指定的ini文件路径,如果没有路径,则在windows目录下查找,如果还是没有则在应用程序目录下查找,再没有,就只能返回def了。
    
            #endregion
    
    
            #region API函数说明
    
            //[DllImport("kernel32")]
            //private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
    
            //[DllImport("kernel32",EntryPoint = "GetPrivateProfileString")]
            //private static extern long GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
    
            [DllImport("kernel32", EntryPoint = "GetPrivateProfileString")]
            private static extern uint GetPrivateProfileStringA(string section, string key, string def, byte[] retVal,
                int size, string filePath);
    
            #endregion
    
            #region 读写INI文件相关
    
            [DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileString", CharSet = CharSet.Ansi)]
            private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
    
            [DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileString", CharSet = CharSet.Ansi)]
            private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal,
                int size, string filePath);
    
            [DllImport("kernel32")]
            private static extern int GetPrivateProfileInt(string lpApplicationName, string lpKeyName, int nDefault,
                string lpFileName);
    
    
            [DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileSectionNames", CharSet = CharSet.Ansi)]
            private static extern int GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, int nSize, string filePath);
    
            [DllImport("KERNEL32.DLL ", EntryPoint = "GetPrivateProfileSection", CharSet = CharSet.Ansi)]
            private static extern int GetPrivateProfileSection(string lpAppName, byte[] lpReturnedString, int nSize,
                string filePath);
    
            #endregion
    
            #region 读写操作(字符串)
    
            //定义一个路径
            public static string filePath = string.Empty;
    
            public static string ReadIniData(string Section, string Key, string NoText)
            {
                return ReadIniData(Section, Key, NoText, filePath);
            }
    
            /// <summary>
            /// 读取INI数据
            /// </summary>
            /// <param name="Section">节点名</param>
            /// <param name="Key">键名</param>
            /// <param name="NoText"></param>
            /// <param name="iniFilePath"></param>
            /// <returns></returns>
            public static string ReadIniData(string Section, string Key, string NoText, string iniFilePath)
            {
                if (File.Exists(iniFilePath))
                {
                    StringBuilder temp = new StringBuilder(1024);
                    GetPrivateProfileString(Section, Key, NoText, temp, 1024, iniFilePath);
                    return temp.ToString();
                }
                else
                {
                    return string.Empty;
                }
            }
    
    
            public static bool WriteIniData(string Section, string Key, string Value)
            {
                return WriteIniData(Section, Key, Value, filePath);
            }
    
            /// <summary>
            /// 向INI写入数据
            /// </summary>
            /// <param name="Section"></param>
            /// <param name="Key"></param>
            /// <param name="Value"></param>
            /// <param name="iniFilePath"></param>
            /// <returns></returns>
            public static bool WriteIniData(string Section, string Key, string Value, string iniFilePath)
            {
                if (!File.Exists(iniFilePath)) File.Create(iniFilePath);
    
                StringBuilder temp = new StringBuilder(1024);
                long OpStation = WritePrivateProfileString(Section, Key, Value, iniFilePath);
                if (OpStation == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
    
            #endregion
    
            #region 配置节信息
    
            /// <summary>
            /// 读取一个ini里面所有的节
            /// </summary>
            /// <param name="sections"></param>
            /// <param name="path"></param>
            /// <returns>-1:没有节信息,0:正常</returns>
            public static int GetAllSectionNames(out string[] sections, string path)
            {
                int MAX_BUFFER = 32767;
                IntPtr pReturnedString = Marshal.AllocCoTaskMem(MAX_BUFFER);
                int bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, path);
                if (bytesReturned == 0)
                {
                    sections = null;
                    return -1;
                }
    
                string local = Marshal.PtrToStringAnsi(pReturnedString, (int) bytesReturned).ToString();
                Marshal.FreeCoTaskMem(pReturnedString);
                //use of Substring below removes terminating null for split
                sections = local.Substring(0, local.Length - 1).Split('\0');
                return 0;
            }
    
            /// <summary>
            /// 返回指定配置文件下的节名称列表
            /// </summary>
            /// <param name="path"></param>
            /// <returns></returns>
            public static List<string> GetAllSectionNames(string path)
            {
                List<string> sectionList = new List<string>();
                int MAX_BUFFER = 32767;
                IntPtr pReturnedString = Marshal.AllocCoTaskMem(MAX_BUFFER);
                int bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, path);
                if (bytesReturned != 0)
                {
                    string local = Marshal.PtrToStringAnsi(pReturnedString, (int) bytesReturned).ToString();
                    Marshal.FreeCoTaskMem(pReturnedString);
                    sectionList.AddRange(local.Substring(0, local.Length - 1).Split('\0'));
                }
    
                return sectionList;
            }
    
            /// <summary>
            /// 获取所有的Sections
            /// </summary>
            /// <param name="iniFilePath"></param>
            /// <returns></returns>
            public static List<string> ReadSections(string iniFilePath)
            {
                List<string> sectionList = new List<string>();
                byte[] buf = new byte[65536];
                uint len = GetPrivateProfileStringA(null, null, null, buf, buf.Length, iniFilePath);
                int j = 0;
                for (int i = 0; i < len; i++)
                {
                    if (buf[i] == 0)
                    {
                        sectionList.Add(Encoding.Default.GetString(buf, j, i - j));
                        j = i + 1;
                    }
                }
    
                return sectionList;
            }
    
            /// <summary>
            /// 获取指定Section下的所有Keys
            /// </summary>
            /// <param name="SectionName"></param>
            /// <param name="iniFilePath"></param>
            /// <returns></returns>
            public static List<string> ReadKeys(string SectionName, string iniFilePath)
            {
                List<string> sectionList = new List<string>();
                byte[] buf = new byte[65536];
                uint len = GetPrivateProfileStringA(null, null, null, buf, buf.Length, iniFilePath);
                int j = 0;
                for (int i = 0; i < len; i++)
                {
                    if (buf[i] == 0)
                    {
                        sectionList.Add(Encoding.Default.GetString(buf, j, i - j));
                        j = i + 1;
                    }
                }
    
                return sectionList;
            }
    
            /// <summary>
            /// 得到某个节点下面所有的key和value组合
            /// </summary>
            /// <param name="section">指定的节名称</param>
            /// <param name="keys">Key数组</param>
            /// <param name="values">Value数组</param>
            /// <param name="path">INI文件路径</param>
            /// <returns></returns>
            public static int GetAllKeyValues(string section, out string[] keys, out string[] values, string path)
            {
                byte[] b = new byte[65535]; //配置节下的所有信息
                GetPrivateProfileSection(section, b, b.Length, path);
                string s = System.Text.Encoding.Default.GetString(b); //配置信息
                string[] tmp = s.Split((char) 0); //Key\Value信息
                List<string> result = new List<string>();
                foreach (string r in tmp)
                {
                    if (r != string.Empty)
                        result.Add(r);
                }
    
                keys = new string[result.Count];
                values = new string[result.Count];
                for (int i = 0; i < result.Count; i++)
                {
                    string[] item = result[i].Split(new char[] {'='}); //Key=Value格式的配置信息
                    //Value字符串中含有=的处理,
                    //一、Value加"",先对""处理
                    //二、Key后续的都为Value
                    if (item.Length > 2)
                    {
                        keys[i] = item[0].Trim();
                        values[i] = result[i].Substring(keys[i].Length + 1);
                    }
    
                    if (item.Length == 2) //Key=Value
                    {
                        keys[i] = item[0].Trim();
                        values[i] = item[1].Trim();
                    }
                    else if (item.Length == 1) //Key=
                    {
                        keys[i] = item[0].Trim();
                        values[i] = "";
                    }
                    else if (item.Length == 0)
                    {
                        keys[i] = "";
                        values[i] = "";
                    }
                }
    
                return 0;
            }
    
            /// <summary>
            /// 得到某个节点下面所有的key
            /// </summary>
            /// <param name="section">指定的节名称</param>
            /// <param name="keys">Key数组</param>
            /// <param name="path">INI文件路径</param>
            /// <returns></returns>
            public static int GetAllKeys(string section, out string[] keys, string path)
            {
                byte[] b = new byte[65535];
    
                GetPrivateProfileSection(section, b, b.Length, path);
                string s = System.Text.Encoding.Default.GetString(b);
                string[] tmp = s.Split((char) 0);
                ArrayList result = new ArrayList();
                foreach (string r in tmp)
                {
                    if (r != string.Empty)
                        result.Add(r);
                }
    
                keys = new string[result.Count];
                for (int i = 0; i < result.Count; i++)
                {
                    string[] item = result[i].ToString().Split(new char[] {'='});
                    if (item.Length == 2)
                    {
                        keys[i] = item[0].Trim();
                    }
                    else if (item.Length == 1)
                    {
                        keys[i] = item[0].Trim();
                    }
                    else if (item.Length == 0)
                    {
                        keys[i] = "";
                    }
                }
    
                return 0;
            }
    
            /// <summary>
            /// 获取指定节下的Key列表
            /// </summary>
            /// <param name="section">指定的节名称</param>
            /// <param name="path">配置文件名称</param>
            /// <returns>Key列表</returns>
            public static List<string> GetAllKeys(string section, string path)
            {
                List<string> keyList = new List<string>();
                byte[] b = new byte[65535];
                GetPrivateProfileSection(section, b, b.Length, path);
                string s = System.Text.Encoding.Default.GetString(b);
                string[] tmp = s.Split((char) 0);
                List<string> result = new List<string>();
                foreach (string r in tmp)
                {
                    if (r != string.Empty)
                        result.Add(r);
                }
    
                for (int i = 0; i < result.Count; i++)
                {
                    string[] item = result[i].Split(new char[] {'='});
                    if (item.Length == 2 || item.Length == 1)
                    {
                        keyList.Add(item[0].Trim());
                    }
                    else if (item.Length == 0)
                    {
                        keyList.Add(string.Empty);
                    }
                }
    
                return keyList;
            }
    
            /// <summary>
            /// 获取值
            /// </summary>
            /// <param name="section"></param>
            /// <param name="path"></param>
            /// <returns></returns>
            public static List<string> GetAllValues(string section, string path)
            {
                List<string> keyList = new List<string>();
                byte[] b = new byte[65535];
                GetPrivateProfileSection(section, b, b.Length, path);
                string s = System.Text.Encoding.Default.GetString(b);
                string[] tmp = s.Split((char) 0);
                List<string> result = new List<string>();
                foreach (string r in tmp)
                {
                    if (r != string.Empty)
                        result.Add(r);
                }
    
                for (int i = 0; i < result.Count; i++)
                {
                    string[] item = result[i].Split(new char[] {'='});
                    if (item.Length == 2 || item.Length == 1)
                    {
                        keyList.Add(item[1].Trim());
                    }
                    else if (item.Length == 0)
                    {
                        keyList.Add(string.Empty);
                    }
                }
    
                return keyList;
            }
    
            #endregion
    
            #region 通过值查找键(一个节中的键唯一,可能存在多个键值相同,因此反查的结果可能为多个)
    
            /// <summary>
            /// 第一个键
            /// </summary>
            /// <param name="section"></param>
            /// <param name="path"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static string GetFirstKeyByValue(string section, string path, string value)
            {
                foreach (string key in GetAllKeys(section, path))
                {
                    if (ReadString(section, key, "", path) == value)
                    {
                        return key;
                    }
                }
    
                return string.Empty;
            }
    
            /// <summary>
            /// 所有键
            /// </summary>
            /// <param name="section"></param>
            /// <param name="path"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static List<string> GetKeysByValue(string section, string path, string value)
            {
                List<string> keys = new List<string>();
                foreach (string key in GetAllKeys(section, path))
                {
                    if (ReadString(section, key, "", path) == value)
                    {
                        keys.Add(key);
                    }
                }
    
                return keys;
            }
    
            #endregion
    
    
            #region 具体类型的读写
    
            #region string
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="keyName"></param>
            /// <param name="defaultValue" />
            /// <param name="path"></param>
            /// <returns></returns>
            public static string ReadString(string sectionName, string keyName, string defaultValue, string path)
            {
                const int MAXSIZE = 255;
                StringBuilder temp = new StringBuilder(MAXSIZE);
                GetPrivateProfileString(sectionName, keyName, defaultValue, temp, 255, path);
                return temp.ToString();
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="keyName"></param>
            /// <param name="value"></param>
            /// <param name="path"></param>
            public static void WriteString(string sectionName, string keyName, string value, string path)
            {
                WritePrivateProfileString(sectionName, keyName, value, path);
            }
    
            #endregion
    
            #region Int
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="keyName"></param>
            /// <param name="defaultValue"></param>
            /// <param name="path"></param>
            /// <returns></returns>
            public static int ReadInteger(string sectionName, string keyName, int defaultValue, string path)
            {
    
                return GetPrivateProfileInt(sectionName, keyName, defaultValue, path);
    
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="keyName"></param>
            /// <param name="value"></param>
            /// <param name="path"></param>
            public static void WriteInteger(string sectionName, string keyName, int value, string path)
            {
    
                WritePrivateProfileString(sectionName, keyName, value.ToString(), path);
    
            }
    
            #endregion
    
            #region bool
    
            /// <summary>
            /// 读取布尔值
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="keyName"></param>
            /// <param name="defaultValue"></param>
            /// <param name="path"></param>
            /// <returns></returns>
            public static bool ReadBoolean(string sectionName, string keyName, bool defaultValue, string path)
            {
    
                int temp = defaultValue ? 1 : 0;
    
                int result = GetPrivateProfileInt(sectionName, keyName, temp, path);
    
                return (result == 0 ? false : true);
    
            }
    
            /// <summary>
            /// 写入布尔值
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="keyName"></param>
            /// <param name="value"></param>
            /// <param name="path"></param>
            public static void WriteBoolean(string sectionName, string keyName, bool value, string path)
            {
                string temp = value ? "1 " : "0 ";
                WritePrivateProfileString(sectionName, keyName, temp, path);
            }
    
            #endregion
    
            #endregion
    
            #region 删除操作
    
            /// <summary>
            /// 删除指定项
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="keyName"></param>
            /// <param name="path"></param>
            public static void DeleteKey(string sectionName, string keyName, string path)
            {
                WritePrivateProfileString(sectionName, keyName, null, path);
            }
    
            /// <summary>
            /// 删除指定节下的所有项
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="path"></param>
            public static void EraseSection(string sectionName, string path)
            {
                WritePrivateProfileString(sectionName, null, null, path);
            }
    
            #endregion
    
            #region 判断节、键是否存在
    
            /// <summary>
            /// 指定节知否存在
            /// </summary>
            /// <param name="section"></param>
            /// <param name="fileName"></param>
            /// <returns></returns>
            public static bool ExistSection(string section, string fileName)
            {
                string[] sections = null;
                GetAllSectionNames(out sections, fileName);
                if (sections != null)
                {
                    foreach (var s in sections)
                    {
                        if (s == section)
                        {
                            return true;
                        }
                    }
                }
    
                return false;
            }
    
            /// <summary>
            /// 指定节下的键是否存在
            /// </summary>
            /// <param name="section"></param>
            /// <param name="key"></param>
            /// <param name="fileName"></param>
            /// <returns></returns>
            public static bool ExistKey(string section, string key, string fileName)
            {
                string[] keys = null;
                GetAllKeys(section, out keys, fileName);
                if (keys != null)
                {
                    foreach (var s in keys)
                    {
                        if (s == key)
                        {
                            return true;
                        }
                    }
                }
    
                return false;
            }
    
            #endregion
    
            #region 同一Section下添加多个Key\Value
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="section"></param>
            /// <param name="keyList"></param>
            /// <param name="valueList"></param>
            /// <param name="path"></param>
            /// <returns></returns>
            public static bool AddSectionWithKeyValues(string section, List<string> keyList, List<string> valueList,
                string path)
            {
                bool bRst = true;
                //判断Section是否已经存在,如果存在,返回false
                //已经存在,则更新
                //if (GetAllSectionNames(path).Contains(section))
                //{
                // return false;
                //}
                //判断keyList中是否有相同的Key,如果有,返回false
    
                //添加配置信息
                for (int i = 0; i < keyList.Count; i++)
                {
                    WriteString(section, keyList[i], valueList[i], path);
                }
    
                return bRst;
            }
    
            #endregion
    
        }
    }
    

      

    【3.2.2】JSON帮助类

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    /*
     * 需要添加引用Newtonsoft.Json.dll
     */
    namespace AutomaticStoreMotionDal
    {
        public class JSONHelper
        {
            /// <summary>
            /// 实体对象转JSON字符串
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="x"></param>
            /// <returns></returns>
            public static string EntityToJSON<T>(T x)
            {
                string result = string.Empty;
                try
                {
                    result = JsonConvert.SerializeObject(x);
                }
                catch (Exception e)
                {
                    result = string.Empty;
                }
    
                return result;
            }
    
            /// <summary>
            /// JSON字符串转实体类
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="json"></param>
            /// <returns></returns>
            public static T JSONToEntity<T>(string json)
            {
                T t = default(T);
                try
                {
                    t = (T) JsonConvert.DeserializeObject(json, typeof(T));
                }
                catch (Exception e)
                {
                    t = default(T);
                }
    
                return t;
            }
        }
    }
    

      

    【3.2】实体类

    【3.2.1】基础参数类

    namespace AutomaticStoreMotionModels
    {
        /// <summary>
        /// 基础参数类
        /// </summary>
       public class BasicParameter
        {
            //X轴称重坐标值
            public double Weight_X { get; set; }
    
            //Y轴称重坐标值
            public double Weight_Y { get; set; }
    
            //Z轴称重坐标值
            public double Weight_Z { get; set; }
    
            //X轴回收坐标值
            public double Recycle_X { get; set; }
    
            //Y轴回收坐标值
            public double Recycle_Y { get; set; }
    
            //Z轴回收坐标值
            public double Recycle_Z { get; set; }
    
            //X轴待机坐标值
            public double Standby_X { get; set; }
    
            //Y轴待机坐标值
            public double Standby_Y { get; set; }
    
            //Z轴待机坐标值
            public double Standby_Z { get; set; }
    
            //X轴初始坐标值
            public double Initial_X { get; set; }
    
            //Y轴初始坐标值
            public double Initial_Y { get; set; }
    
            //Z轴库位坐标值
            public double Initial_Z { get; set; }
    
            //X轴偏移坐标值
            public double Offset_X { get; set; }
    
            //Y轴偏移坐标值
            public double Offset_Y { get; set; }
    
            //Z轴安全坐标值
            public double Offset_Z { get; set; }
    
            //X轴自动运行速度
            public double SpeedAuto_X { get; set; }
    
            //Y轴自动运行速度
            public double SpeedAuto_Y { get; set; }
    
            //Z轴自动运行速度
            public double SpeedAuto_Z { get; set; }
    
            //X轴手动运行速度
            public double SpeedHand_X { get; set; } = 15;
    
            //Y轴手动运行速度
            public double SpeedHand_Y { get; set; } = 2;
    
            //Z轴手动运行速度
            public double SpeedHand_Z { get; set; } = 1;
    
            //系统参数
    
            //称重端口
            public string WeightPort { get; set; } = "COM1";
    
            //扫码枪端口
            public string ScannerPort { get; set; } = "COM2";
    
            //称重波特率
            public int WeightBaud { get; set; } = 9600;
    
            //扫码枪波特率
            public int ScannerBaud { get; set; } = 9600;
    
            //称重参数
            public string WeightParmeter { get; set; } = "N81";
    
            //扫码枪参数
            public string ScannerParmeter { get; set; } = "N81";
    
            //空瓶重量
            public double EmptyWeight { get; set; } = 12.0f;
    
            //冗余重量
            public double RedundancyWeight { get; set; } = 1.0f;
    
            //允许入库数量
            public int AllowInCount { get; set; } = 100;
    
            //允许出库数量
            public int AllowOutCount { get; set; } = 3;
    
            //自动锁定间隔 单位秒
            public int AtuoLock { get; set; } = 100;
        }
    }
    

     

    【3.2.2】高级参数类

    namespace AutomaticStoreMotionModels
    {
        /// <summary>
        /// 高级参数类
        /// </summary>
        public class AdvancedParameter
        {
            //卡号
            public short CardNo { get; set; } = 1;
    
            //轴数量
            public short AxisCount { get; set; } = 4;
    
            //X轴
            public short Axis_X { get; set; } = 1;
    
            //Y轴
            public short Axis_Y { get; set; } = 2;
    
            //Z轴
            public short Axis_Z { get; set; } = 3;
    
            //U轴
            public short Axis_U { get; set; } = 4;
    
            //输入输出
    
            //存料按钮
            public short StoreButton { get; set; } = 1;
    
            //取料按钮
            public short ReclaimButton { get; set; } = 2;
    
            //急停按钮
            public short EmergencyButton { get; set; } = 3;
    
            //夹子打开到位
            public short ClipOpen { get; set; } = 4;
    
            //夹子关闭到位
            public short ClipClose { get; set; } =5;
    
            //存料指示
            public short StoreState { get; set; } = 1;
    
            //取料指示
            public short ReclaimState { get; set; } = 2;
    
            //模式指示
            public short ModeState { get; set; } = 3;
    
            //夹子控制
            public short ClipCtrl { get; set; } = 4;
    
            //上左门控制
            public short TopLeftDoor { get; set; } = 5;
    
            //上后门控制
            public short TopBehindDoor { get; set; } = 6;
    
            //上右门控制
            public short TopRightDoor { get; set; } = 7;
    
            //下前门控制
            public short BottomBehindDoor { get; set; } = 8;
    
            //照明控制
            public short LightCtrl { get; set; } = 9;
    
            //总行数
            public short RowCount { get; set; } = 10;
    
            //总列数
            public short ColumnCount { get; set; } = 9;
    
            //运动控制卡配置文件
            public string Cfg { get; set; } = "thinger";
    
            //脉冲当量(1个毫米对应多少个脉冲)
    
            //X轴缩放系数
            public double Scale_X { get; set; } = 4000;
    
            //Y轴缩放系数
            public double Scale_Y { get; set; } = 4000;
    
            //Z轴缩放系数
            public double Scale_Z { get; set; } = 4000;
    
            //加速度
            //X轴运动加速度
            public double Acc_X { get; set; } = 0.01;
    
            //Y轴运动加速度
            public double Acc_Y { get; set; } = 0.01;
    
            //Z轴运动加速度
            public double Acc_Z { get; set; } = 0.01;
    
    
            //复位方向
        }
    }
    

     

    【3.2.3】操作结果的类 

    namespace AutomaticStoreMotionModels
    {
        /// <summary>
        /// 操作结果的类
        /// </summary>
        public class OperationResult
        {
            /// <summary>
            /// 是否成功
            /// </summary>
            public bool IsSuccess { get; set; }
    
            /// <summary>
            /// 错误信息
            /// </summary>
            public string ErrorMsg { get; set; }
    
            /// <summary>
            /// 返回成功的操作结果
            /// </summary>
            /// <returns></returns>
            public static OperationResult CreateSuccessResult()
            {
                return new OperationResult()
                {
                    IsSuccess = true,
                    ErrorMsg = "OK"
    
                };
            }
    
            /// <summary>
            /// 返回失败的操作结果
            /// </summary>
            /// <returns></returns>
            public static OperationResult CreateFailResult()
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = "NG"
    
                };
            }
        }
    }
    

    4,新建一个公共方法,参数对象和参数保存和加载方法 

    namespace AutomaticStoreMotionDal
    {
        /// <summary>
        /// 公共方法
        /// </summary>
        public class CommonMethods
        {
            #region 参数配置
    
            /// <summary>
            /// 基础参数
            /// </summary>
            public static BasicParameter basicParameter = new BasicParameter();
    
            /// <summary>
            /// 高级参数
            /// </summary>
            public static AdvancedParameter advancedParameter = new AdvancedParameter();
    
    
            /// <summary>
            /// 配置文件路径
            /// </summary>
            public static string configFile = Application.StartupPath + "\\Config\\Config.ini";
    
            /// <summary>
            /// 保存基础参数【把对象转字符串保存在配置文件,保存修改参数时调用的方法】
            /// </summary>
            /// <returns>操作结果</returns>
            public static OperationResult SaveBasicParmetmer()
            {
                //先将对象转JSON字符串
                string json = JSONHelper.EntityToJSON(basicParameter);
    
                //把json字符写入INI
                if (IniConfigHelper.WriteIniData("参数", "基础参数", json, configFile))
                {
                    return OperationResult.CreateSuccessResult();
                }
                else
                {
                    return OperationResult.CreateFailResult();
                }
            }
    
            /// <summary>
            /// 保存高级参数【把对象转字符串保存在配置文件,保存修改参数时调用的方法】
            /// </summary>
            /// <returns>操作结果</returns>
            public static OperationResult SaveAdvancedParmetmer()
            {
                //先将对象转JSON字符串
                string json = JSONHelper.EntityToJSON(advancedParameter);
    
                //把json字符写入INI
                if (IniConfigHelper.WriteIniData("参数", "高级参数", json, configFile))
                {
                    return OperationResult.CreateSuccessResult();
                }
                else
                {
                    return OperationResult.CreateFailResult();
                }
            }
    
            /// <summary>
            /// 参数加载【主窗体加载的时候调用,配置文件转对象】
            /// </summary>
            /// <returns></returns>
            public static OperationResult LoadParameter()
            {
                try
                {
                    //获取INI文件中的基础参数json字符串
                    string jsonBasic =
                        IniConfigHelper.ReadIniData("参数", "基础参数", JSONHelper.EntityToJSON(basicParameter), configFile);
    
                    //json转对象
                    if (!string.IsNullOrEmpty(jsonBasic)) //防止第一用的时候配置文件不存,basicParameter=null,导致参数加载都是空
                        basicParameter = JSONHelper.JSONToEntity<BasicParameter>(jsonBasic);
    
                    //获取INI文件中的高级参数json字符串
                    string jsonAdvanced = IniConfigHelper.ReadIniData("参数", "高级参数",
                        JSONHelper.EntityToJSON(advancedParameter), configFile);
    
                    //json转对象
                    if (!string.IsNullOrEmpty(jsonAdvanced)) //防止第一用的时候配置文件不存,basicParameter=null,导致参数加载都是空
                        advancedParameter = JSONHelper.JSONToEntity<AdvancedParameter>(jsonAdvanced);
                }
                catch (Exception e)
                {
                    return new OperationResult()
                    {
                        IsSuccess = false,
                        ErrorMsg = e.Message //从这里获取错误的信息
                    };
                }
    
                return OperationResult.CreateSuccessResult();
            }
    
            #endregion
        }
    }
    

      

    5,参数设置界面

    【5.1】界面UI

    注意:控件的Name要跟对象属性名称保持一致

    【5.2】 参数设置代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.IO.Ports;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using AutomaticStoreMotionDal;
    using AutomaticStoreMotionModels;
    
    namespace AutomaticStoreMotionPro
    {
        public partial class FrmparameterSet : Form
        {
            public enum SerialParameter
            {
                N81,
                N71,
                E81,
                O81,
                O71
            }
    
            public FrmparameterSet()
            {
                InitializeComponent();
    
                //端口号
                this.WeightPort.DataSource = SerialPort.GetPortNames();
                this.ScannerPort.DataSource = SerialPort.GetPortNames();
                //波特率
                this.WeightBaud.DataSource=new string[]{"4800","9600","19200","38400"};
                this.WeightBaud.DataSource=new string[]{"4800","9600","19200","38400"};
                //参数
                this.WeightParmeter.DataSource = Enum.GetNames(typeof(SerialParameter));
                this.ScannerParmeter.DataSource = Enum.GetNames(typeof(SerialParameter));
    
                //方向
    
                //配置
                DirectoryInfo directoryInfo = new DirectoryInfo(Application.StartupPath + "\\Config");
                foreach (FileInfo file in directoryInfo.GetFiles("*.cfg"))
                {
                    this.Cfg.Items.Add(file.Name);
                }
    
                //读取配置文件给控件显示
                InitialParameter(this.tabPage1, CommonMethods.basicParameter);
                InitialParameter(this.tabPage2, CommonMethods.advancedParameter);
            }
    
    
            /// <summary>
            /// 加载参数【把对象属性的值赋值给控件显示】
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="tabPage">容器</param>
            /// <param name="obj">对象</param>
            private void InitialParameter<T>(TabPage tabPage,T obj)
            {
                foreach (var item in tabPage.Controls)
                {
                    if (item is NumericUpDown numeric)
                    {
                        //获取控件的名称
                        string propertyName = numeric.Name;
                        //通过控件的名称,拿到对象属性的值
                        string value = GetObjectPropertyVaule(obj, propertyName);
    
                        if (value != null && value.Length > 0)
                        {
                            if (decimal.TryParse(value, out decimal val))
                            {
                                //把对象属性的值赋值给控件显示
                                numeric.Value = val;
                            }
                        }
    
                    }
                    else if(item is ComboBox cmb)
                    {
                        //获取控件的名称
                        string propertyName = cmb.Name;
                        //通过控件的名称,拿到对象属性的值
                        string value = GetObjectPropertyVaule(obj, propertyName);
                        //把对象的值赋值给控件显示
                        if (value != null) cmb.Text = value;
                    }
                }
            }
    
            /// <summary>
            /// 修改参数【根据控件名称给对象的属性赋值】
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="parameterType">参数类型</param>
            /// <param name="obj">对象</param>
            private void ModifyParameter<T>(string parameterType,T obj)
            {
                StringBuilder sb=new StringBuilder();
    
                foreach (var item in this.tab_main.SelectedTab.Controls)
                {
                    if (item is NumericUpDown numeric)
                    {
                        //获取控件的名称(控件的名称对应的是对象属性的名称)
                        string propertyName = numeric.Name;
                        //通过对象属性名称拿到属性的值
                        string value = GetObjectPropertyVaule(obj, propertyName);
    
                        //如果控制的值和对象属性的值不一致,表示有修改动作
                        if (value.Length>0&& numeric.Value.ToString() != value)
                        {
                            //添加修改记录
                            sb.Append(numeric.Tag.ToString() + "修改为:" + numeric.Value.ToString() + "; ");
                            //通过属性名称给对象的属性赋值
                            SetObjectPropertyVaule(obj, propertyName, numeric.Value.ToString());
                        }
                    }
                    else if(item is ComboBox cmb)
                    {
                        //获取控件的名称(控件的名称对应的是对象属性的名称)
                        string propertyName = cmb.Name;
                        //通过对象属性名称拿到属性的值
                        string value = GetObjectPropertyVaule(obj, propertyName);
                        //如果控制的值和对象属性的值不一致,表示有修改动作
                        if (value.Length > 0 && cmb.Text != value)
                        {
                            //添加修改记录
                            sb.Append(cmb.Tag.ToString() + "修改为:" + cmb.Text.ToString() + "; ");
                            //通过属性名称给对象的属性赋值
                            SetObjectPropertyVaule(obj, propertyName, cmb.Text.ToString());
                        }
                    }               
                }
    
                if (sb.ToString().Length > 0)
                {
                    OperationResult result = parameterType == "基础参数"
                        ? CommonMethods.SaveBasicParmetmer()
                        : CommonMethods.SaveAdvancedParmetmer();
                    if (result.IsSuccess)
                    {
                        //写入数据库
                        if (!SysLogService.AddSysLog(new SysLog(sb.ToString(), "触发", LogTye.操作记录, GlobalVariable.SysAdmin.LoginName)))
                        {
                            NLogHelper.Error("参数修改记录写入数据库出错");
                        };
    
                        MessageBox.Show(parameterType+"修改成功", "参数修改");
         
                    }
                    else
                    {
                        MessageBox.Show(parameterType + "修改失败", "参数修改");
                    }
                }
                else
                {
                    MessageBox.Show("参数未做任何修改", "参数修改");
                }
            }
    
            /// <summary>
            /// 通过属性名称获对象属性的值
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="obj">对象</param>
            /// <param name="propertyName">属性名称</param>
            /// <returns>返回值</returns>
            private string GetObjectPropertyVaule<T>(T obj, string propertyName)
            {
                try
                { 
                    Type type = typeof(T);
                    PropertyInfo property = type.GetProperty(propertyName);
                    if (property == null)
                    {
                        return string.Empty;
                    }
    
                    object val = property.GetValue(obj, null);
                    return val?.ToString();
    
                }
                catch (Exception e)
                {
                    NLogHelper.Info("通过属性名获取值",e.Message);
                    return null;
                }
            }
    
            /// <summary>
            /// 通过属性名称给对象的属性赋值
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="obj">对象</param>
            /// <param name="propertyName">属性名称</param>
            /// <param name="value">值</param>
            /// <returns></returns>
            private bool SetObjectPropertyVaule<T>(T obj, string propertyName,string value)
            {
                try
                {
                    Type type = typeof(T);
                    object t = Convert.ChangeType(value, type.GetProperty(propertyName).PropertyType);
                    type.GetProperty(propertyName).SetValue(obj,t,null);
                    return true;
    
                }
                catch (Exception e)
                {
                    return false;
                }
            }
    
            //保存修改
            private void btn_modifyBasic_Click(object sender, EventArgs e)
            {
                ModifyParameter("基础参数", CommonMethods.basicParameter);
            }
    
            //取消修改
            private void btn_cancelBasic_Click(object sender, EventArgs e)
            {
                InitialParameter(this.tab_main.SelectedTab, CommonMethods.basicParameter);
            }
    
            //保存修改
            private void btn_modifyAdvanced_Click(object sender, EventArgs e)
            {
                ModifyParameter("高级参数", CommonMethods.advancedParameter);
            }
    
            //取消修改
            private void btn_cancelAdvanced_Click(object sender, EventArgs e)
            {
                InitialParameter(this.tab_main.SelectedTab, CommonMethods.advancedParameter);
            }
        }
    }
    

      

    6,配置文件结果:

    E:\VS workspace\学习C sharp运动控制\AutomaticStoreMotionPro\AutomaticStoreMotionPro\bin\Debug\Config

    [参数]
    基础参数={"Weight_X":1.0,"Weight_Y":2.0,"Weight_Z":3.0,"Recycle_X":0.0,"Recycle_Y":0.0,"Recycle_Z":0.0,"Standby_X":0.0,"Standby_Y":0.0,"Standby_Z":0.0,"Initial_X":0.0,"Initial_Y":0.0,"Initial_Z":0.0,"Offset_X":0.0,"Offset_Y":0.0,"Offset_Z":0.0,"SpeedAuto_X":0.0,"SpeedAuto_Y":0.0,"SpeedAuto_Z":0.0,"SpeedHand_X":17.0,"SpeedHand_Y":2.0,"SpeedHand_Z":2.0,"WeightPort":"COM1","ScannerPort":"COM2","WeightBaud":9600,"ScannerBaud":9600,"WeightParmeter":"N81","ScannerParmeter":"N81","EmptyWeight":12.0,"RedundancyWeight":1.0,"AllowInCount":100,"AllowOutCount":3,"AutoLock":0}
    高级参数={"CardNo":1,"AxisCount":4,"Axis_X":1,"Axis_Y":2,"Axis_Z":3,"Axis_U":4,"StoreButton":3,"ReclaimButton":2,"EmergencyButton":1,"ClipOpen":4,"ClipClose":5,"StoreState":1,"ReclaimState":2,"ModeState":3,"ClipCtrl":4,"TopLeftDoor":5,"TopBehindDoor":6,"TopRightDoor":7,"BottomBehindDoor":8,"LightCtrl":9,"RowCount":10,"ColumnCount":9,"Cfg":"thinger","Scale_X":4000.0,"Scale_Y":4000.0,"Scale_Z":4000.0,"Acc_X":0.01,"Acc_Y":0.01,"Acc_Z":0.01,"HomeDir_X":null,"HomePos_X":0,"HomeNeg_X":0,"HomeOffset_X":0}

  • 相关阅读:
    jdk8中奖Date转换为String格式的方法
    Java Calendar详解
    Java Calendar使用总结
    得到当前时间的小时数
    Java中 break continue return 的区别
    两个QWidget叠加,可部分代替layout的功能
    Qt5官方demo解析集35——Music Player(使用winextras模块)
    P和P1指向了O和O1两个变量(对象)的地址, 而不是O和O1的内容(对象的实际地址)——充分证明@是取变量(对象)的地址,而不是变量里面的内容,够清楚!
    提高Android和iOS调试编译速度
    Delphi 快速获取文件大小(使用_lopen和FileSeek,此函数可以快速获取文件大小,即使文件已经被其它程序锁定)
  • 原文地址:https://www.cnblogs.com/baozi789654/p/15627009.html
Copyright © 2020-2023  润新知