using DataEntity;
|
using DataEntity.Share;
|
using HxEnum;
|
using System;
|
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
using System.Configuration;
|
using System.Linq;
|
using System.Net.Sockets;
|
using System.Reflection;
|
using System.Security.Cryptography;
|
using System.Text;
|
using System.Text.RegularExpressions;
|
using System.Windows.Media;
|
using System.Xml;
|
using XCommon.Log;
|
using XImagingXhandler.XDAL;
|
using static HxEnum.DataTypeEnum;
|
|
namespace XCommon
|
{
|
/// <summary>
|
/// 共用类
|
/// </summary>
|
public class ComUtility
|
{
|
#region 获取配置参数
|
/// <summary>
|
/// 获取配置参数
|
/// </summary>
|
/// <returns></returns>
|
public static bool GetConfigParams()
|
{
|
bool bIsOk = false;
|
string strValue = string.Empty;
|
double dValue = 0d;
|
|
try
|
{
|
do
|
{
|
#region 窗体显示尺寸
|
Shared.Config.DisplaySizeW = 1920d;
|
Shared.Config.DisplaySizeH = 1080d;
|
Shared.Config.DisplayMarginTop = 0d;
|
|
#region 窗体显示尺寸
|
if (!GetConfigValue("displaySize", out strValue))
|
{
|
break;
|
}
|
|
string[] displaySizes = strValue.Split('*');
|
if (displaySizes.Length == 2)
|
{
|
if (!ParseToDouble(displaySizes[0], out dValue))
|
{
|
break;
|
}
|
Shared.Config.DisplaySizeW = dValue;
|
|
if (!ParseToDouble(displaySizes[1], out dValue))
|
{
|
break;
|
}
|
Shared.Config.DisplaySizeH = dValue;
|
}
|
#endregion
|
|
#region 窗体显示距顶距离
|
if (!GetConfigValue("displayMarginTop", out strValue))
|
{
|
break;
|
}
|
if (!ParseToDouble(strValue, out dValue))
|
{
|
break;
|
}
|
Shared.Config.DisplayMarginTop = dValue;
|
#endregion
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
bIsOk = true;
|
}
|
while (false);
|
}
|
catch (Exception ex)
|
{
|
LoggerHelper.ErrorLog("ERROR:", ex);
|
}
|
|
return bIsOk;
|
}
|
|
/// <summary>
|
/// 获取Config的值
|
/// </summary>
|
/// <param name="key"></param>
|
/// <returns></returns>
|
public static bool GetConfigValue(string key, out string value)
|
{
|
value = ConfigurationManager.AppSettings.Get(key);
|
if (value == null)
|
{
|
LoggerHelper.ErrorLog(string.Format("[GetConfigValue]: Key:{0}, Value:{1}", key, value));
|
return false;
|
}
|
|
return true;
|
}
|
#endregion
|
|
#region 获取Guid
|
/// <summary>
|
/// 获取Guid
|
/// </summary>
|
/// <returns></returns>
|
public static string GetGuid()
|
{
|
return Guid.NewGuid().ToString("N");
|
}
|
#endregion
|
|
#region 获取MD5值
|
/// <summary>
|
/// 获取MD5值
|
/// </summary>
|
/// <param name="strVal"></param>
|
/// <returns></returns>
|
public static string GetMD5(string strVal)
|
{
|
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
|
byte[] bytValue, bytHash;
|
bytValue = Encoding.UTF8.GetBytes(strVal);
|
bytHash = md5.ComputeHash(bytValue);
|
md5.Clear();
|
string sTemp = "";
|
for (int i = 0; i < bytHash.Length; i++)
|
{
|
sTemp += bytHash[i].ToString("X").PadLeft(2, '0');
|
}
|
return sTemp.ToLower();
|
}
|
#endregion
|
|
#region 有效孔字符串转换成List
|
/// <summary>
|
/// 有效孔字符串转换成List
|
/// </summary>
|
/// <param name="strValidWells"></param>
|
/// <returns></returns>
|
public static List<string> GetValidWells(string strValidWells)
|
{
|
List<string> lstValidWells = new List<string>();
|
|
if (!string.IsNullOrEmpty(strValidWells))
|
{
|
string[] validWellsArry = strValidWells.Split(',');
|
lstValidWells = validWellsArry.ToList();
|
}
|
|
return lstValidWells;
|
}
|
#endregion
|
|
#region 获取放盖位名称
|
/// <summary>
|
/// 获取放盖位名称
|
/// </summary>
|
/// <param name="strValidWells"></param>
|
/// <returns></returns>
|
public static List<string> GetPlateCoverLatticeName()
|
{
|
string coatingCoverLatticeId = ConfigurationManager.AppSettings["coatingCoverLatticeId"].ToString();
|
// 涂布的板放盖位号:P2,P3
|
List<string> listCoatingCoverLatticeId = coatingCoverLatticeId.Split(',').ToList();
|
return listCoatingCoverLatticeId;
|
}
|
#endregion
|
|
#region 根据输入的行数,取得对应的字符串名称
|
/// <summary>
|
/// 根据输入的行数,取得对应的字符串名称
|
/// </summary>
|
/// <param name="rowNum">当前的行号</param>
|
/// <returns>该行对应的字母</returns>
|
public static string GetRowChar(int rowNum)
|
{
|
var a = rowNum / 26;
|
var b = rowNum % 26;
|
|
if (a > 0) return GetRowChar(a - 1) + (char)(b + 65);
|
|
return ((char)(b + 65)).ToString();
|
}
|
#endregion
|
|
#region 根据输入的行字母,取得对应的行号
|
/// <summary>
|
/// 根据输入的行字母,取得对应的行号
|
/// </summary>
|
/// <param name="rowName">当前的行字母</param>
|
/// <returns>该行号</returns>
|
public static string GetRowIndexByRowChar(string rowName)
|
{
|
int currentValue = Convert.ToInt32(rowName.ToCharArray()[0]);
|
return (currentValue - 65).ToString();
|
}
|
#endregion
|
|
|
#region 根据输入的行名称,取得对应的行index
|
public static int GetRowIndex(string col)
|
{
|
if (string.IsNullOrEmpty(col))
|
{
|
return -1;
|
}
|
return (Convert.ToChar(col) - 65);
|
}
|
#endregion
|
|
#region 根据输入的行编号,取得对应的行名称
|
public static string GetRowName(string rowNum)
|
{
|
return Convert.ToChar((Convert.ToInt32(rowNum) + 65)).ToString();
|
}
|
#endregion
|
|
#region 获取列号: A11 -> 11
|
/// <summary>
|
/// 获取列号
|
/// </summary>
|
/// <param name="wellName"></param>
|
/// <returns></returns>
|
public static int GetColNum(string wellName)
|
{
|
string colNum = Regex.Replace(wellName, "[A-Za-z ]", string.Empty);
|
return int.Parse(colNum);
|
}
|
#endregion
|
|
#region 获取行字母: A11 -> A
|
/// <summary>
|
/// 获取行字母
|
/// </summary>
|
/// <param name="wellName"></param>
|
/// <returns></returns>
|
public static string GetRowChar(string wellName)
|
{
|
return Regex.Replace(wellName, "[0-9 ]", string.Empty);
|
}
|
#endregion
|
|
#region 获取吸头盒、孔板有效孔位信息
|
/// <summary>
|
/// 获取吸头盒、孔板有效孔位信息
|
/// </summary>
|
/// <param name="rowCount"></param>
|
/// <param name="columnCount"></param>
|
/// <returns></returns>
|
public static string GetValidWells(int rowCount, int columnCount)
|
{
|
string validWells = string.Empty;
|
for (int i = 1; i < rowCount + 1; i++)
|
{
|
string rowName = ComUtility.GetRowChar(i - 1);
|
for (int j = 1; j < columnCount + 1; j++)
|
{
|
string wellName = rowName + j.ToString();
|
validWells += wellName + ",";
|
}
|
}
|
|
if (!string.IsNullOrEmpty(validWells))
|
{
|
validWells = validWells.Substring(0, validWells.Length - 1);
|
}
|
|
return validWells;
|
}
|
#endregion
|
|
#region 从xml中获取通道数组值
|
/// <summary>
|
/// 从xml中获取通道数组值
|
/// </summary>
|
/// <param name="xmlChs"></param>
|
/// <returns></returns>
|
public static int[] GetChannelsFromXml(string xmlChs)
|
{
|
int[] nArrayChs = new int[0];
|
|
if (xmlChs.Contains(","))
|
{
|
string[] chs = xmlChs.Split(',');
|
nArrayChs = Array.ConvertAll<string, int>(chs, s => int.Parse(s));
|
}
|
else
|
{
|
if (!string.IsNullOrEmpty(xmlChs))
|
{
|
nArrayChs = new int[1] { Convert.ToInt32(xmlChs) };
|
}
|
}
|
|
var channelList = nArrayChs.ToList();
|
channelList.Sort();
|
nArrayChs = channelList.ToArray();
|
|
return nArrayChs;
|
}
|
#endregion
|
|
#region 根据板位别名和台面信息xml查找到对应唯一板位节点
|
/// <summary>
|
/// 根据板位别名和台面信息xml查找到对应唯一板位
|
/// </summary>
|
/// <param name="platformList"></param>
|
/// <param name="boardName"></param>
|
/// <returns></returns>
|
public static XmlNode GetXmlNodeByBoardName(XmlNodeList platformList, string boardName)
|
{
|
XmlNode result = null;
|
|
for (int i = 0; i < platformList.Count; i++)
|
{
|
XmlNodeList labwareNodeList = platformList[i].SelectNodes("labware");
|
|
var labwareSrcNode = labwareNodeList[0].SelectSingleNode("labware_sname[text()='" + boardName + "']");
|
if (labwareSrcNode != null)
|
{
|
result = platformList[i];
|
break;
|
}
|
}
|
return result;
|
}
|
#endregion
|
|
#region 根据枚举值获取下拉值
|
public static List<DropdownName> GetDropDownList<T>()
|
{
|
List<DropdownName> dropdownNames = new List<DropdownName>();
|
var dicCommunicateType = EnumManagement.EnumToDictionaryValue<T>();
|
foreach (var dicItem in dicCommunicateType)
|
{
|
dropdownNames.Add(new DropdownName() { dropdown_id = dicItem.Key, dropdown_name = dicItem.Value });
|
}
|
return dropdownNames;
|
}
|
#endregion
|
|
#region 判断Socket是否连接上,需要通过发包来确认: (这个方法也不能解决物理掉线问题,比如拔网线)
|
/// <summary>
|
/// 判断Socket是否连接上,需要通过发包来确认: (这个方法也不能解决物理掉线问题,比如拔网线)
|
/// </summary>
|
/// <param name="client"></param>
|
/// <returns></returns>
|
public static bool IsSocketConnected(Socket client)
|
{
|
if (client != null)
|
{
|
bool blockingState = client.Blocking;
|
try
|
{
|
byte[] tmp = new byte[1];
|
client.Blocking = false;
|
client.Send(tmp, 0, 0);
|
return true;
|
}
|
catch (SocketException e)
|
{
|
// 产生 10035 == WSAEWOULDBLOCK 错误,说明被阻止了,但是还是连接的
|
if (e.NativeErrorCode.Equals(10035))
|
return true;
|
else
|
return false;
|
}
|
finally
|
{
|
client.Blocking = blockingState; // 恢复状态
|
}
|
}
|
return true;
|
}
|
#endregion
|
|
#region 数据转换
|
#region 字符串转Image
|
/// <summary>
|
/// 字符串转Image
|
/// </summary>
|
/// <param name="base64String"></param>
|
/// <returns></returns>
|
public static ImageSource StringToImag(string base64String)
|
{
|
if (string.IsNullOrEmpty(base64String))
|
return null;
|
byte[] bytes = System.Convert.FromBase64String(base64String);
|
|
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
|
ImageSourceConverter imageSourceConverter = new ImageSourceConverter();
|
ImageSource source = null;
|
source = (ImageSource)imageSourceConverter.ConvertFrom(ms);
|
|
return source;
|
}
|
#endregion
|
|
#region 转成数字类型
|
/// <summary>
|
/// 转成数字类型
|
/// </summary>
|
/// <param name="valueSource"></param>
|
/// <param name="valueTarget"></param>
|
/// <returns></returns>
|
public static bool ParseToInt(string valueSource, out int valueTarget)
|
{
|
if (!int.TryParse(valueSource, out valueTarget))
|
{
|
LoggerHelper.ErrorLog(string.Format("ParseToInt,value = {0}, 参数不是Int!!!", valueSource));
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
#endregion
|
|
#region 转成double类型
|
/// <summary>
|
/// 转成double类型
|
/// </summary>
|
/// <param name="valueSource"></param>
|
/// <param name="valueTarget"></param>
|
/// <returns></returns>
|
public static bool ParseToDouble(string valueSource, out double valueTarget)
|
{
|
if (!double.TryParse(valueSource, out valueTarget))
|
{
|
LoggerHelper.ErrorLog(string.Format("ParseToDouble,value = {0}, 参数不是double!!!", valueSource));
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
#endregion
|
|
#region 转成bool类型
|
/// <summary>
|
/// 转成bool类型
|
/// </summary>
|
/// <param name="valueSource"></param>
|
/// <param name="valueTarget"></param>
|
/// <returns></returns>
|
public static bool ParseToBool(string valueSource, ref bool valueTarget)
|
{
|
if (!bool.TryParse(valueSource, out valueTarget))
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
#endregion
|
|
#region 转成DateTime类型
|
/// <summary>
|
/// 转成DateTime类型
|
/// </summary>
|
/// <param name="valueSource"></param>
|
/// <param name="valueTarget"></param>
|
/// <returns></returns>
|
public static bool ParseToDateTime(string valueSource, out DateTime valueTarget)
|
{
|
if (!DateTime.TryParse(valueSource, out valueTarget))
|
{
|
LoggerHelper.ErrorLog(string.Format("ParseToDateTime,value = {0}, 参数不是DateTime!!!", valueSource));
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
#endregion
|
#endregion
|
|
#region 根据行/列有效数量计算列的批次信息
|
/// <summary>
|
/// 根据行/列有效数量计算列的批次信息
|
/// </summary>
|
/// <param name="wells"></param>
|
/// <param name="channels"></param>
|
/// <param name="dilutionDirectionValue"></param>
|
/// <returns></returns>
|
public static List<List<TipsTable>> GetWellBatchInfo(List<TipsTable> wells, int[] channels,
|
DilutionDirectionEnum dilutionDirectionValue)
|
{
|
List<List<TipsTable>> lstWellBatchInfo = new List<List<TipsTable>>();
|
|
int oneGroupCnt = 0;
|
// 从左到右
|
if (dilutionDirectionValue == DilutionDirectionEnum.LeftToRight)
|
{
|
// 一组数量先定义为枪头的数量
|
oneGroupCnt = channels.Length;
|
|
// 384孔:16行 * 24列
|
for (int i = 1; i <= 24; i++)
|
{
|
var selWells = wells.Where(it => ComUtility.GetColNum(it.wellname) == i);
|
if (selWells.Any())
|
{
|
List<TipsTable> colList = selWells.ToList();
|
// 一组数量取最小值
|
oneGroupCnt = Math.Min(oneGroupCnt, colList.Count);
|
|
var groups = Enumerable.Range(0, (colList.Count + oneGroupCnt - 1) / oneGroupCnt)
|
.Select((j, index) => colList.Skip(index * oneGroupCnt).Take(oneGroupCnt)).ToList();
|
|
foreach (var group in groups)
|
{
|
lstWellBatchInfo.Add(group.ToList());
|
}
|
}
|
}
|
}
|
// 从上到下
|
else if (dilutionDirectionValue == DilutionDirectionEnum.UpToDown)
|
{
|
// 384孔:16行 * 24列
|
for (int i = 1; i <= 24; i++)
|
{
|
var selWells = wells.Where(it => ComUtility.GetColNum(it.wellname) == i);
|
if (selWells.Any())
|
{
|
List<TipsTable> colList = selWells.ToList();
|
// 一组数量取最小值
|
oneGroupCnt = 1;
|
|
var groups = Enumerable.Range(0, (colList.Count + oneGroupCnt - 1) / oneGroupCnt)
|
.Select((j, index) => colList.Skip(index * oneGroupCnt).Take(oneGroupCnt)).ToList();
|
|
foreach (var group in groups)
|
{
|
lstWellBatchInfo.Add(group.ToList());
|
}
|
}
|
}
|
}
|
// 从下到上
|
else if (dilutionDirectionValue == DilutionDirectionEnum.DownToUp)
|
{
|
// 384孔:16行 * 24列
|
for (int i = 1; i <= 24; i++)
|
{
|
var selWells = wells.Where(it => ComUtility.GetColNum(it.wellname) == i);
|
if (selWells.Any())
|
{
|
List<TipsTable> colList = selWells.ToList();
|
colList.Reverse();
|
// 一组数量取最小值
|
oneGroupCnt = 1;
|
|
var groups = Enumerable.Range(0, (colList.Count + oneGroupCnt - 1) / oneGroupCnt)
|
.Select((j, index) => colList.Skip(index * oneGroupCnt).Take(oneGroupCnt)).ToList();
|
|
foreach (var group in groups)
|
{
|
lstWellBatchInfo.Add(group.ToList());
|
}
|
}
|
}
|
}
|
|
return lstWellBatchInfo;
|
}
|
#endregion
|
|
#region 数据类型转换
|
/// <summary>
|
/// 数据类型转换
|
/// </summary>
|
/// <param name="value"></param>
|
/// <param name="type"></param>
|
/// <returns></returns>
|
public static object ToTypeConvert(string value, string type)
|
{
|
var sfsd = EnumManagement.GetALLEnum<DataTypeEnum_Parameter>();
|
|
Dictionary<string, object> dic = new Dictionary<string, object>();
|
if (EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.Varchar ||
|
EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.Datetime ||
|
EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.JSON)
|
{
|
return value;
|
}
|
else if (EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.Int)
|
{
|
return Convert.ToInt32(value);
|
}
|
else if (EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.Bool)
|
{
|
return Convert.ToBoolean(value);
|
}
|
else if (EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.Double)
|
{
|
return Convert.ToDouble(value);
|
}
|
else if (EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.USHORT)
|
{
|
return Convert.ToUInt16(value);
|
}
|
else if (EnumManagement.ToEnum<DataTypeEnum_Parameter>(type) == DataTypeEnum_Parameter.BYTE)
|
{
|
return Convert.ToByte(value);
|
}
|
return dic;
|
}
|
#endregion
|
|
#region RGB转Color
|
/// <summary>
|
/// RGB转Color
|
/// </summary>
|
/// <param name="strRGB"></param>
|
/// <returns></returns>
|
public static Color RGBToColor(string strRGB)
|
{
|
Color color = Colors.WhiteSmoke;
|
if (string.IsNullOrEmpty(strRGB))
|
{
|
return color;
|
}
|
|
string[] strRgbArray = strRGB.Split(',');
|
if (strRgbArray.Length < 3)
|
{
|
return color;
|
}
|
|
int[] nRgbArray = Array.ConvertAll(strRgbArray, int.Parse);
|
|
color = Color.FromRgb((byte)nRgbArray[0], (byte)nRgbArray[1], (byte)nRgbArray[2]);
|
return color;
|
}
|
#endregion
|
|
#region 对相同属性名称值复制Value
|
/// <summary>
|
/// 对相同属性名称值复制Value
|
/// </summary>
|
/// <typeparam name="D">新对象</typeparam>
|
/// <typeparam name="S">原始对象</typeparam>
|
/// <param name="s">原始对象</param>
|
/// <param name="isCopyStruct">是否只复制结构类型(包括string类型)</param>
|
/// <returns></returns>
|
public static D MapperStruct<D, S>(S s)
|
{
|
D d = Activator.CreateInstance<D>();
|
try
|
{
|
var Types = s.GetType();// 获得类型
|
var Typed = typeof(D);
|
foreach (PropertyInfo sp in Types.GetProperties())
|
{
|
foreach (PropertyInfo dp in Typed.GetProperties())
|
{
|
if (dp.Name.Equals(sp.Name))
|
{
|
dp.SetValue(d, sp.GetValue(s, null), null);
|
}
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
throw ex;
|
}
|
return d;
|
}
|
#endregion
|
|
#region 根据字符串分割成下拉值
|
/// <summary>
|
/// 根据字符串分割成下拉值
|
/// </summary>
|
/// <param name="value"></param>
|
/// <returns></returns>
|
public static ObservableCollection<DropdownName> GetDropDownList(string value)
|
{
|
ObservableCollection<DropdownName> dropDownList = new ObservableCollection<DropdownName>();
|
|
string[] ChoiceModelTypes = value.Split(';');
|
for (int index = 0; index < ChoiceModelTypes.Length; index++) // 模型类型
|
{
|
string[] modelType = ChoiceModelTypes[index].Split('-');
|
DropdownName dropdownName = new DropdownName();
|
dropdownName.dropdown_id = modelType[0];
|
dropdownName.dropdown_name = modelType[1];
|
dropDownList.Add(dropdownName);
|
}
|
|
return dropDownList;
|
}
|
#endregion
|
|
#region 根据keyId名称查找方法节点属性
|
/// <summary>
|
/// 根据keyId名称查找方法节点属性
|
/// </summary>
|
/// <param name="mEx"></param>
|
/// <param name="keyId"></param>
|
/// <returns></returns>
|
public static MethodEx FindMethodExByKeyId(MethodEx mEx, string keyId)
|
{
|
if (mEx.tag != null && ((XImagingXhandler.XDAL.MethodBase)mEx.tag).keyId == keyId)
|
{
|
return mEx;
|
}
|
else
|
{
|
if (mEx.Children.Count > 0)
|
{
|
foreach (var m in mEx.Children)
|
{
|
MethodEx find = FindMethodExByKeyId(m, keyId);
|
if (find != null)
|
{
|
return find;
|
}
|
}
|
}
|
|
if (mEx.SubMethod != null)
|
{
|
MethodEx find = FindMethodExByKeyId(mEx.SubMethod, keyId);
|
if (find != null)
|
{
|
return find;
|
}
|
}
|
else
|
{
|
return null;
|
}
|
}
|
return null;
|
}
|
#endregion
|
}
|
}
|