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}

 


免責聲明!

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



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