2026-01-26 18:56:53 +09:00

1029 lines
36 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using System.Management;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace CoreUnit.Common
{
public class UtilUnit
{
public enum IOType { DI, DO, AI, AO };
public enum ReactiveLayerStateType //ReactiveLayer 상태
{
IDLE, //초기화 전
READY, //초기화 후
RUN,
PAUSE,//일시 정지
HEAVYALARM, //Heavy Alarm
LIGHTALARM
};
public enum ReactiveLayerOperationType //ReactiveLayer 운전 모드
{
None,
Manual,
SemiAuto,
DryRun,
Auto
};
public static LogUnit logUnit = new LogUnit();
public static Dictionary<string, UtilUnit.ControlLanguage> ControlLanguages = new Dictionary<string, UtilUnit.ControlLanguage>();
public enum eLanguage { Korean, English };
public class ControlLanguage
{
public string controlName = "";
public string koreanName = "";
public string englishName = "";
public ControlLanguage(string control, string korean, string english)
{
controlName = control;
koreanName = korean;
englishName = english;
}
}
public static List<System.Windows.Forms.Control> GetAllControls(System.Windows.Forms.Control control)
{
List<System.Windows.Forms.Control> controlList = new List<System.Windows.Forms.Control>();
foreach (System.Windows.Forms.Control ctrl in control.Controls)
{
controlList.Add(ctrl);
if (ctrl.Controls.Count > 0)
{
controlList.AddRange(GetAllControls(ctrl));
}
}
return controlList;
}
public static List<ToolStripItem> GetAllToolStripItems(ToolStrip toolStrip)
{
List<ToolStripItem> toolStripItems = new List<ToolStripItem>();
foreach (ToolStripItem item in toolStrip.Items)
{
toolStripItems.Add(item);
if (item is ToolStripMenuItem)
{
toolStripItems.AddRange(GetAllToolStripMenuItems((ToolStripMenuItem)item));
}
}
return toolStripItems;
}
public static List<ToolStripMenuItem> GetAllToolStripMenuItems(ToolStripMenuItem toolStripMenuItem)
{
List<ToolStripMenuItem> toolStripMenuItems = new List<ToolStripMenuItem>();
foreach (ToolStripMenuItem item in toolStripMenuItem.DropDownItems)
{
toolStripMenuItems.Add(item);
if (item.DropDownItems.Count > 0)
{
toolStripMenuItems.AddRange(GetAllToolStripMenuItems(item));
}
}
return toolStripMenuItems;
}
#region Registry
public static string GetRegistryValue(string keyName, string valueName, string defaultValue)
{
object value = Microsoft.Win32.Registry.GetValue(keyName, valueName, defaultValue);
if(value == null)
{
return defaultValue;
}
return value.ToString();
}
public static double GetRegistryValue(string keyName, string valueName, double defaultValue)
{
string str = GetRegistryValue(keyName, valueName, defaultValue.ToString());
double value = 0;
if(false == double.TryParse(str, out value))
{
return defaultValue;
}
return value;
}
public static int GetRegistryValue(string keyName, string valueName, int defaultValue)
{
string str = GetRegistryValue(keyName, valueName, defaultValue.ToString());
int value = 0;
if(false == int.TryParse(str, out value))
{
return defaultValue;
}
return value;
}
public static void SetRegistryValue(string keyName, string valueName, string value)
{
string defaultValue = "";
string temp = GetRegistryValue(keyName, valueName, defaultValue);
if(temp != value)
{
Microsoft.Win32.Registry.SetValue(keyName, valueName, value);
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, System.Reflection.MethodBase.GetCurrentMethod().Name, string.Format("Registry Changed [keyName : {0}], [valueName : {1}], [value : {2} → {3}]", keyName, valueName, temp, value) );
}
}
public static void SetRegistryValue(string keyName, string valueName, double value)
{
double defaultValue = -1;
double temp = GetRegistryValue(keyName, valueName, defaultValue);
if(temp != value)
{
Microsoft.Win32.Registry.SetValue(keyName, valueName, value);
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, System.Reflection.MethodBase.GetCurrentMethod().Name, string.Format("Registry Changed [keyName : {0}], [valueName : {1}], [value : {2} → {3}]", keyName, valueName, temp, value) );
}
}
public static void SetRegistryValue(string keyName, string valueName, int value)
{
int defaultValue = -1;
int temp = GetRegistryValue(keyName, valueName, defaultValue);
if(temp != value)
{
Microsoft.Win32.Registry.SetValue(keyName, valueName, value);
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, System.Reflection.MethodBase.GetCurrentMethod().Name, string.Format("Registry Changed [keyName : {0}], [valueName : {1}], [value : {2} → {3}]", keyName, valueName, temp, value) );
}
}
#endregion Registry
#region Data 처리
public static string ConvertShortArrayToString(short[] array)
{
System.Text.StringBuilder buf = new System.Text.StringBuilder();
int maxIndex = array.Length - 1;
for (int i = 0; i <= maxIndex; i++)
{
buf.Append(array[i]);
}
return buf.ToString();
}
public static List<double> ShiftData(List<double> data, double shift)
{
List<double> shiftData = new List<double>();
foreach (double val in data)
{
shiftData.Add(val - shift);
}
return shiftData;
}
public static byte[] ConvertHexStringToByteArray(string hexString)
{
if (hexString.Length % 2 != 0)
{
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
}
byte[] HexAsBytes = new byte[hexString.Length / 2];
for (int index = 0; index < HexAsBytes.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
Array.Reverse(HexAsBytes);
return HexAsBytes;
}
public static double DegreeToRadian(double angle)
{
return Math.PI * angle / 180.0;
}
public static double RadianToDegree(double radian)
{
return radian * (180.0 / Math.PI);
}
public static List<bool> ConvertDecimalToBinary(int vlaue)
{
int binary;
char[] binaryHolder = new char[1];
string binaryResult="";
while (vlaue > 0)
{
binary = vlaue % 2;
binaryResult += binary;
vlaue = vlaue / 2;
}
binaryHolder = binaryResult.ToCharArray();
Array.Reverse(binaryHolder);
binaryResult = new string(binaryHolder);
List<bool> binaryList = new List<bool>();
return binaryList;
}
public static int CutValue(int value, int min, int max)
{
if(value > max)
{
return max;
}
else if(value < min)
{
return min;
}
else
{
return value;
}
}
public static string ConvertStringStreamFromList(List<double> posList)
{
string currPos = "";
for (int i = 0; i < posList.Count; i++)
{
currPos += string.Format("{0:F5},", posList[i]);
}
currPos = currPos.Remove(currPos.LastIndexOf(','));
return currPos;
}
public static string ConvertStringStreamFromDateTimeList(List<int> dateTimeList)
{
string currPos = "";
for (int i = 0; i < dateTimeList.Count; i++)
{
currPos += dateTimeList[i]+",";
}
currPos = currPos.Remove(currPos.LastIndexOf(','));
return currPos;
}
public static List<double> ConvertListFromStringStream(string posStream)
{
List<double> posList = new List<double>();
string[] token = posStream.Split(',');
for (int tokenIndex = 0; tokenIndex < token.Length; tokenIndex++)
{
posList.Add(Convert.ToDouble(token[tokenIndex]));
}
return posList;
}
public static List<string> ConvertAxisIDListFromAxisIDStream(string axisIDStream)
{
List<string> axisIDList = new List<string>();
string[] token = axisIDStream.Split(',');
for (int tokenIndex = 0; tokenIndex < token.Length; tokenIndex++)
{
axisIDList.Add(token[tokenIndex]);
}
return axisIDList;
}
public static Color ConvertColorFromStringStream(string str)
{
string[] spstring = str.Split(',');
if(spstring.Length == 1)
return Enum.TryParse(str, true, out KnownColor color)
? Color.FromKnownColor(color)
: Color.White;
int[] iNumber = spstring
.Select(s => int.Parse(Regex.Replace(s, @"\D", "")))
.ToArray();
if (spstring.Length == 4) // ARGB
return Color.FromArgb(iNumber[0], iNumber[1], iNumber[2], iNumber[3]);
if (spstring.Length == 3) // RGB
return Color.FromArgb(0xFF, iNumber[0], iNumber[1], iNumber[2]);
return Color.White;
}
public static List<double> Threshold(List<double> data, double thresholdMin, double thresholdMax)
{
List<double> thresholdData = new List<double>();
foreach(double val in data)
{
if(thresholdMin <= val && val <= thresholdMax)
{
thresholdData.Add(val);
}
}
return thresholdData;
}
public static List<double> Median1D(List<double> data, int filterLength)
{
int middleNo = filterLength % 2 + 1;
List<double> filteredData = new List<double>();
for(int iNo = 0; iNo <= data.Count - filterLength; iNo++)
{
List<double> temp = data.GetRange(iNo, filterLength);
temp.Sort();
filteredData.Add(temp[middleNo]);
}
return filteredData;
}
public static List<double> MovingAverage(List<double> data, int filterLength)
{
List<double> filteredData = new List<double>();
for (int iNo = 0; iNo <= data.Count - filterLength; iNo++)
{
filteredData.Add(data.GetRange(iNo, filterLength - 1).Average());
}
return filteredData;
}
public static List<double> Minimum(List<double> data, int filterLength)
{
List<double> filteredData = new List<double>();
for(int iNo = 0; iNo <= data.Count - filterLength; iNo++)
{
filteredData.Add(Minimum(data.GetRange(iNo, filterLength - 1)));
}
return filteredData;
}
public static double Minimum(List<double> data)
{
double temp = 9999.99;
for (int i = 0; i < data.Count; i++)
{
temp = Math.Min(data[i], temp);
}
return temp;
}
public static List<double> Maximum(List<double> data, int filterLength)
{
List<double> filteredData = new List<double>();
for(int iNo = 0; iNo <= data.Count - filterLength; iNo++)
{
filteredData.Add(Maximum(data.GetRange(iNo, filterLength - 1)));
}
return filteredData;
}
public static double Maximum(List<double> data)
{
double temp = -9999.99;
for (int i = 0; i < data.Count; i++)
{
temp = Math.Max(data[i], temp);
}
return temp;
}
public static List<double> Derivative(List<double> data, int interbal)
{
List<double> derivativeData = new List<double>();
for(int i = 0; i < data.Count - interbal; i++)
{
double value = (data[i + interbal] - data[i]) / interbal;
derivativeData.Add(value);
}
return derivativeData;
}
#endregion Data 처리
#region 파일 관리 기능
public static string GetFileExtension(string filePath)
{
return Path.GetExtension(filePath);
}
public static string GetFileName(string filePath)
{
return Path.GetFileName(filePath);
}
public static string GetFileNameWithoutExtension(string filePath)
{
return Path.GetFileNameWithoutExtension(filePath);
}
public static string GetDirectoryName(string filePath)
{
return Path.GetDirectoryName(filePath);
}
public static string CombineFileName(string path1,string path2)//경로의 구분자인 역슬레쉬를 안 넣어줘도 됨
{
return Path.Combine(path1, path2);
}
#endregion
#region INI 파일 읽기 및 쓰기
[DllImport("kernel32.dll")]
private static extern int GetPrivateProfileString(string section,string key,string def,StringBuilder retVal,int size,string filePath);
[DllImport("kernel32.dll")]
private static extern long WritePrivateProfileString(string section,string key,string val,string filePath);
// INI 값을 읽어 온다.
public static void GetIniValue(string fileName, string section, string key, ref string value)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(section, key, "", temp, 255, fileName);
value = temp.ToString();
}
public static void GetIniValue(string fileName, string section, string key, ref int value)
{
string temp= string.Empty;
GetIniValue(fileName, section, key,ref temp);
value = Convert.ToInt32(temp);
}
public static void GetIniValue(string fileName, string section, string key, ref double value)
{
string temp = string.Empty;
GetIniValue(fileName, section, key, ref temp);
value = Convert.ToDouble(temp);
}
public static void GetIniValue(string fileName, string section, string key, ref uint value)
{
string temp = string.Empty;
GetIniValue(fileName, section, key, ref temp);
value = Convert.ToUInt32(temp);
}
// INI 값을 셋팅
public static void SetIniValue(string fileName, string section, string Key, string value)
{
WritePrivateProfileString(section, Key, value, fileName);
}
public static void SetIniValue(string fileName, string section, string Key, int value)
{
WritePrivateProfileString(section, Key, value.ToString(), fileName);
}
public static void SetIniValue(string fileName, string section, string Key, double value)
{
WritePrivateProfileString(section, Key, value.ToString(), fileName);
}
#endregion
#region 좌표 변환(translation) 기능
public static void TranslateCoordination(PointF originalPt, ref PointF translatedPt, float angle=0, PointF center=new PointF())//Angle는 degree
{
float rad = (float)(angle * Math.PI / 180);
translatedPt.X = (float)((originalPt.X - center.X) * Math.Cos(rad) - (originalPt.Y - center.Y) * Math.Sin(rad) + center.X);
translatedPt.Y = (float)((originalPt.X - center.X) * Math.Sin(rad) + (originalPt.Y - center.Y) * Math.Cos(rad) + center.Y);
}
#endregion
#region 비트 연산
public static byte[] BitArrayToByteArray(BitArray bits)
{
byte[] ret = new byte[(bits.Length - 1) / 8 + 1];
bits.CopyTo(ret, 0);
return ret;
}
#endregion
#region 5.시스템 메모리 확인 기능
enum MemorySizeType { Byte, KB, MB, GB, TB }
static ManagementClass cls = new ManagementClass("Win32_OperatingSystem");
static int ctrlTitleDisplayCount = 0;
static int writeFileCount = 0;
static string strMemorySize = "";
public static string GetCurrentProcessMemorySize()
{
long usageMemory = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
string retStr = string.Empty;
StringBuilder sb = new System.Text.StringBuilder();
int i = 0;
while (usageMemory > 1024L) { usageMemory = (Int64)(usageMemory / 1024L); i++; }
MemorySizeType sizeType = (MemorySizeType)i;
sb.AppendFormat("Process Memory: {0} {1}", usageMemory, sizeType.ToString()); retStr = sb.ToString();
return sb.ToString();
}
public static string GetCurrentFreePhysicalMemorySize()
{
int memorySize = 0;
ManagementObjectCollection instances = cls.GetInstances();
foreach (ManagementObject instance in instances)
{
memorySize = int.Parse(instance["FreePhysicalMemory"].ToString());
}
return string.Format("Free Physical Memory: {0:#,###} MB", memorySize / 1024);
}
public static void UpdateSystemMemory(int periodTime/*단위는 ms*/, System.Windows.Forms.Control ctrl, string title, bool isWriteToFile)
{
if (periodTime * ctrlTitleDisplayCount > 100000) //updateTime 초 이상 지나면 control title 업데이트
{
ctrlTitleDisplayCount = 0;
strMemorySize = string.Format("{0} ({1}, {2})", title, GetCurrentProcessMemorySize(), GetCurrentFreePhysicalMemorySize());
}
else
{
ctrlTitleDisplayCount++;
}
if ((isWriteToFile) && (periodTime * writeFileCount > 3600000)) //1시간 지나면 저장함.
{
writeFileCount = 0;
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, MethodBase.GetCurrentMethod().Name, strMemorySize, LogUnit.eLogLevel.LOW);
}
else
{
writeFileCount++;
}
}
#endregion
#region 6.현재 코드 위치, 함수 이름 가져오기
public static string GetCurrentStackFrameInfo()
{
StackTrace st = new StackTrace(true);
StackFrame sf = st.GetFrame(1);
MethodBase m = sf.GetMethod();
return string.Format("{0}({1}), {2}.{3}", sf.GetFileName(), sf.GetFileLineNumber(), m.ReflectedType.FullName, m.Name);
}
public static string GetCurrentMethodFullName()
{
StackTrace st = new StackTrace(true);
StackFrame sf = st.GetFrame(1);
MethodBase m = sf.GetMethod();
return string.Format("{0}.{1}", m.ReflectedType.FullName, m.Name);
}
#endregion
#region 기하 계산 함수 모음
/// <summary>
/// 두 점을 잇는 직선의 기울기를 구하는 함수
/// </summary>
/// <param name="lp1">첫번째 점</param>
/// <param name="lp2">두번째 점</param>
/// <returns>두 점을 잇는 직선의 기술기. 단위는 Radian</returns>
public static double LineAngle(Point lp1, Point lp2)
{
if (lp1.X == lp2.X)
{
if (lp1.Y > lp2.Y)
return Math.PI * 6 / 4;
if (lp1.Y < lp2.Y)
return Math.PI / 2;
return 0;
}
// first find angle A
double adjacent = lp2.X - lp1.X;
double opposite = lp2.Y - lp1.Y;
// find angle A
double A = Math.Atan(opposite / adjacent);
if (adjacent < 0) // 2nd and 3rd quadrant
A += Math.PI; // + 180
if (adjacent > 0 && opposite < 0) // 4th quadrant
A += Math.PI * 2; // +360
return A;
}
public static double LineAngleDegree(Point lp1, Point lp2)
{
double radian = LineAngle(lp1, lp2);
return radian * 180 / Math.PI;
}
public static double LineDistance(PointF p1, PointF p2, bool abs = true)
{
double dx = p1.X - p2.X;
double dy = p1.Y - p2.Y;
if (abs)
{
dx = Math.Abs(dx);
dy = Math.Abs(dy);
}
if (dx == 0)
return dy;
if (dy == 0)
return dx;
return Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
}
public static List<PointF> LineDividePoint(PointF startPoint, PointF endPoint, int divideCount)
{
List<PointF> dividedPoint = new List<PointF>();
if (divideCount != 0)
{
//등분 거리
double dx = (endPoint.X - startPoint.X) / divideCount;
double dy = (endPoint.Y - startPoint.Y) / divideCount;
for (int i = 0; i < divideCount; i++)
{
double pointX = dx * i + startPoint.X;
double pointY = dy * i + startPoint.Y;
dividedPoint.Add(new PointF((float)pointX, (float)pointY));
}
}
else
{
dividedPoint.Add(startPoint);
}
return dividedPoint;
}
#region Linear Regression
public static void LinearRegression(List<PointF> point, out double yIntercept, out double slope)
{
//참고 링크 : https://en.wikipedia.org/wiki/Simple_linear_regression#Numerical_example
double sumOfX = 0;
double sumOfY = 0;
double sumOfXSq = 0;
double sumOfYSq = 0;
double sumCodeviates = 0;
for (int i = 0; i < point.Count; i++)
{
double x = point[i].X;
double y = point[i].Y;
sumCodeviates += x * y;
sumOfX += x;
sumOfY += y;
sumOfXSq += x * x;
sumOfYSq += y * y;
}
double count = point.Count;
double ssX = sumOfXSq - ((sumOfX * sumOfX) / count);
double ssY = sumOfYSq - ((sumOfY * sumOfY) / count);
double rNumerator = (count * sumCodeviates) - (sumOfX * sumOfY);
double rDenom = (count * sumOfXSq - (sumOfX * sumOfX)) * (count * sumOfYSq - (sumOfY * sumOfY));
double sCo = sumCodeviates - ((sumOfX * sumOfY) / count);
double meanX = sumOfX / count;
double meanY = sumOfY / count;
double dblR = rNumerator / Math.Sqrt(rDenom);
yIntercept = meanY - ((sCo / ssX) * meanX);
slope = sCo / ssX;
}
#endregion
#endregion
#region 문자열 처리
public static string Right(string target, int length)
{
if (length <= target.Length)
{
return target.Substring(target.Length - length);
}
else
{
return string.Empty;
}
}
#endregion
public static bool PushButton(object sender, bool bConfirm = true)
{
logUnit.SetLog(LogUnit.eLogType.BUTTON, MethodBase.GetCurrentMethod().Name, string.Format("[{0}]-[{1}] button is pushed", (sender as Button).Name, (sender as Button).Text), LogUnit.eLogLevel.MIDDLE);
if(bConfirm == true)
{
if(DialogResult.No == MessageBox.Show(string.Format("Do you want to do [{0}]?", (sender as Button).Text), "confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
{
logUnit.SetLog(LogUnit.eLogType.BUTTON, MethodBase.GetCurrentMethod().Name, string.Format("[{0}]-[{1}] button is canceled", (sender as Button).Name, (sender as Button).Text), LogUnit.eLogLevel.MIDDLE);
return false;
}
logUnit.SetLog(LogUnit.eLogType.BUTTON, MethodBase.GetCurrentMethod().Name, string.Format("[{0}]-[{1}] button is confirmed", (sender as Button).Name, (sender as Button).Text), LogUnit.eLogLevel.MIDDLE);
}
return true;
}
}
#region Xml 읽고 쓰는 함수
public class XmlSerializable : System.Attribute
{
public XmlSerializable() { }
}
public class XmlUtil
{
public static void AddProperty(string name, object value, XmlWriter wr)
{
string svalue = string.Empty;
if (value is string)
{
svalue = value as string;
}
if (svalue.Length == 0 && value.GetType() == typeof(float))
{
svalue = XmlConvert.ToString(Math.Round((float)value, 8));
}
if (svalue.Length == 0 && value.GetType() == typeof(double))
{
svalue = XmlConvert.ToString(Math.Round((double)value, 8));
}
if (svalue.Length == 0)
{
svalue = value.ToString();
}
wr.WriteStartElement("property");
wr.WriteAttributeString("name", name);
wr.WriteAttributeString("value", svalue);
wr.WriteEndElement();
}
public static void ParseProperty(XmlElement node, object dataobject)
{
if (node.Name != "property")
return;
string fieldname = node.GetAttribute("name");
string svalue = node.GetAttribute("value");
if (fieldname.Length == 0 || svalue.Length == 0)
return;
PropertyInfo info = CommonPropertyUtil.GetProperty(dataobject, fieldname);
if (info == null || info.CanWrite == false)
return;
try
{
object value = PropertyUtil.ChangeType(svalue, info.PropertyType);
if (value != null)
info.SetValue(dataobject, value, null);
}
catch { };
}
public static void ParseProperties(XmlElement itemnode, object dataobject)
{
foreach (XmlElement propertynode in itemnode.ChildNodes)
XmlUtil.ParseProperty(propertynode, dataobject);
}
public static void WriteProperties(object dataobject, XmlWriter wr)
{
foreach (PropertyInfo propertyInfo in dataobject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
XmlSerializable attr = (XmlSerializable)Attribute.GetCustomAttribute(propertyInfo, typeof(XmlSerializable));
if (attr != null)
{
string name = propertyInfo.Name;
object value = propertyInfo.GetValue(dataobject, null);
if (value != null)
{
AddProperty(name, value, wr);
}
}
}
}
}
public class PropertyUtil
{
public static object ChangeType(object value, Type type)
{
if (type == typeof(RectangleF))
return CommonPropertyUtil.Parse(value.ToString(), type);
if (type == typeof(Rectangle))
return CommonPropertyUtil.Parse(value.ToString(), type);
if (type == typeof(PointF))
return CommonPropertyUtil.Parse(value.ToString(), type);
return CommonPropertyUtil.ChangeType(value, type);
}
}
public class CommonPropertyUtil
{
private static PropertyInfo GetNestedProperty(object dataobject, string[] nestedfields, int curindex, ref object nestedDataObject)
{
nestedDataObject = dataobject;
string fieldname = nestedfields[curindex];
PropertyInfo property = GetProperty(dataobject, fieldname);
if (property == null)
return null;
dataobject = property.GetValue(dataobject, null);
curindex++;
if (curindex == nestedfields.Length)
return property;
return GetNestedProperty(dataobject, nestedfields, curindex, ref nestedDataObject);
}
public static PropertyInfo GetNestedProperty(object dataobject, ref object nestedDataObject, string fullFieldname)
{
string[] names = fullFieldname.Split('.');
return GetNestedProperty(dataobject, names, 0, ref nestedDataObject);
}
public static PropertyInfo GetNestedProperty(ref object dataobject, string fullFieldname)
{
return GetNestedProperty(dataobject, ref dataobject, fullFieldname);
}
public static PropertyInfo GetProperty(object dataobject, string propertyname)
{
if (dataobject == null)
return null;
return GetProperty(dataobject.GetType(), propertyname);
}
public static PropertyInfo GetProperty(Type dataobjecttype, string propertyname)
{
MemberInfo[] members = dataobjecttype.GetMember(propertyname);
foreach (MemberInfo member in members)
{
PropertyInfo property = (member as PropertyInfo);
if (property != null)
return property;
}
return null;
}
private static bool IsPrimitive(object obj)
{
if (obj == null)
return false;
Type type = obj.GetType();
if (type.IsPrimitive || type.IsEnum || type == typeof(string))
return true;
return false;
}
public static object ChangeType(object value, Type type)
{
if (value.GetType() == type)
return value;
//if (IsClass(value))
//{
// if (value.GetType().IsSubclassOf(type))
// return value;
// return value;
//}
if (value.GetType() == typeof(string) && type.IsEnum)
{
try
{
return Enum.Parse(type, value.ToString());
}
catch
{
}
}
if (type.IsPrimitive == false)
{
object obj = Parse(value.ToString(), type);
if (obj != null)
return obj;
}
try
{
return Convert.ChangeType(value, type);
}
catch { }
return null;
}
static public object Parse(string value, Type type)
{
if (type == typeof(System.Drawing.SizeF))
return Parse(new System.Drawing.SizeF(0, 0), value);
if (type == typeof(System.Drawing.Size))
return Parse(new System.Drawing.Size(0, 0), value);
if (type == typeof(System.Drawing.PointF))
return Parse(new System.Drawing.PointF(0, 0), value);
if (type == typeof(System.Drawing.Point))
return Parse(new System.Drawing.Point(0, 0), value);
if (type == typeof(System.Drawing.Rectangle))
return Parse(new System.Drawing.Rectangle(0, 0,10,10), value);
if (type == typeof(System.Drawing.Color))
{
value = value.Replace("Color ", "");
value = value.Trim(new char[] { '[', ']' });
System.Drawing.Color c = System.Drawing.Color.FromName(value);
if (c.IsKnownColor)
return c;
ColorWrapper color = new ColorWrapper();
Parse(color, value);
return color.Color;
}
if (type == typeof(System.Drawing.RectangleF))
{
return Parse(new System.Drawing.RectangleF(0, 0, 0, 0), value);
}
return null;
}
public static void ParseProperty(string fieldname, string svalue, object dataobject)
{
if (fieldname.Length == 0 || svalue.Length == 0)
return;
PropertyInfo info = GetProperty(dataobject, fieldname);
if (info == null || info.CanWrite == false)
return;
try
{
object value = ChangeType(svalue, info.PropertyType);
if (value != null)
info.SetValue(dataobject, value, null);
}
catch { };
}
public static object Parse(object obj, string valuestring)
{
// string will be in format '{property=value, property=value}'
valuestring = valuestring.Trim(new char[] { '{', '}' });
string[] properties = valuestring.Split(',');
foreach (string propertyvalue in properties)
{
string[] propvaluepair = propertyvalue.Split('=');
if (propvaluepair.Length != 2)
continue;
string fieldname = propvaluepair[0].Trim();
string value = propvaluepair[1].Trim();
ParseProperty(fieldname, value, obj);
}
return obj;
}
internal class ColorWrapper
{
int a = 0, r = 0, g = 0, b = 0;
public int A
{
get { return a; }
set { a = value; }
}
public int R
{
get { return r; }
set { r = value; }
}
public int G
{
get { return g; }
set { g = value; }
}
public int B
{
get { return b; }
set { b = value; }
}
public System.Drawing.Color Color
{
get { return System.Drawing.Color.FromArgb(a, r, g, b); }
}
}
}
#endregion
}