ParticlesGridDevidePage.cs 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629
  1. using OTSCommon.DBOperate;
  2. using OTSCommon.DBOperate.Model;
  3. using OTSIncAReportApp;
  4. using OTSIncAReportApp._1_UI.Control_Grids.ParticlesGridDevidePage;
  5. using OTSIncAReportApp._2_CommonFunction.CommonClass;
  6. using OTSIncAReportApp._3_ServiceCenter.DataOperation.DataAccess;
  7. using OTSIncAReportApp.DataOperation.DataAccess;
  8. using OTSIncAReportApp.OTSRstMgrFunction;
  9. using OTSIncAReportApp.SysMgrTools;
  10. using OTSIncAReportGraph.Class;
  11. using OTSIncAReportGraph.Controls;
  12. using OTSIncAReportGraph.OTSIncAReportGraphFuncation;
  13. using OTSIncAReportGrids.OTSIncAReportGridsFuncation;
  14. using OTSIncAReportMailInterface;
  15. using System;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Data;
  19. using System.Data.SQLite;
  20. using System.Drawing;
  21. using System.IO;
  22. using System.Linq;
  23. using System.Reflection;
  24. using System.Threading;
  25. using System.Windows.Forms;
  26. using static OTSDataType.otsdataconst;
  27. namespace OTSIncAReportGrids
  28. {
  29. public partial class ParticlesGridDevidePage : UserControl
  30. {
  31. #region 变量定义
  32. private ParticlesGridDevidePageShowConfig m_particlesGridDevidePageShowConfig = null;
  33. //设置模拟数据表
  34. public DataTable m_dt = new DataTable();
  35. //底层操作类
  36. private SEMAndEDSOperate m_OTSIncAReportGridsFun = null;
  37. //进度条窗体
  38. public Frm_UserProgress m_frm_userprogress;
  39. //移动SEM到指定位置发生线程
  40. private Thread m_mythread;
  41. //记录线程是否已经运行完成的状态
  42. private bool m_mythread_state = false;
  43. //导出图像文件的路径
  44. private string m_imagefilepath = "";
  45. //显示元素列表
  46. public List<string> m_list_elementscolname = null;
  47. //单个数据源所拥有的列数,这里保存下来,供导出模块使用
  48. public int m_oneresult_columncount = 0;
  49. private OTSImageDisHelp m_ReportFun = null;
  50. public OTSImageDisHelp ReportFun
  51. {
  52. get => m_ReportFun;
  53. set => m_ReportFun = value;
  54. }
  55. /// <summary>
  56. /// 选择颗粒缓存表
  57. /// </summary>
  58. private List<Particle> Particleslist_selecttodisplay = new List<Particle>();
  59. //多个数据源,每个数据源拥有的列数,这里保存下来,供分组使用
  60. public List<int> m_list_oneresult_columncount;
  61. //国际化
  62. private Language lan;
  63. public Hashtable table;
  64. //测量结果
  65. public ResultFile result = null;
  66. private frmReportConditionChoose m_condition;
  67. private FieldData fieldData;
  68. private DataTable particlesAll;
  69. private DataTable particlesFilter;
  70. public ParticleData Particledata;
  71. public UserSTDDbAccess userSTDDb;
  72. public FieldAndParticleImage fldImgAccess;
  73. private DataTable userSTDDbData;
  74. List<string> elementTypeSort;
  75. private readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
  76. private enum SelItem
  77. {
  78. analyticalParticle = 0,
  79. otherParticles = 1,
  80. MergeParticles = 2,
  81. allParticles = 3
  82. }
  83. #region 分页器相关
  84. #region 分页字段和属性
  85. private string condition = "";
  86. public string FileName = null;
  87. private int pageIndex = 1;
  88. /// <summary>
  89. /// 当前页面
  90. /// </summary>
  91. public virtual int PageIndex
  92. {
  93. get { return pageIndex; }
  94. set { pageIndex = value; }
  95. }
  96. private int pageSize = 20;
  97. /// <summary>
  98. /// 每页记录数
  99. /// </summary>
  100. public virtual int PageSize
  101. {
  102. get { return pageSize; }
  103. set { pageSize = value; }
  104. }
  105. private int recordCount = 0;
  106. /// <summary>
  107. /// 总记录数
  108. /// </summary>
  109. public virtual int RecordCount
  110. {
  111. get { return recordCount; }
  112. set { recordCount = value; }
  113. }
  114. private int pageCount = 0;
  115. /// <summary>
  116. /// 总页数
  117. /// </summary>
  118. public int PageCount
  119. {
  120. get
  121. {
  122. pageCount = GetPageCount();
  123. return pageCount;
  124. }
  125. }
  126. /// <summary>
  127. /// 计算总页数
  128. /// </summary>
  129. /// <returns></returns>
  130. private int GetPageCount()
  131. {
  132. if (PageSize <= 0)
  133. {
  134. return 0;
  135. }
  136. return (RecordCount + PageSize - 1) / PageSize;
  137. }
  138. #endregion
  139. private frmReportApp m_ReportApp;
  140. #endregion
  141. #endregion
  142. #region UI层方法
  143. #region 初始化
  144. public ParticlesGridDevidePage(frmReportApp ReportApp)
  145. {
  146. m_ReportApp = ReportApp;
  147. m_condition = ReportApp.m_conditionChoose;
  148. string sou = m_condition.m_CurrentConditions[OTSIncAReportApp.OTSSampleReportInfo.OTS_REPORT_PROP_GRID_ITEMS.DATA_SOURCE].itemDisplayVal.ToString();
  149. if (sou.Contains("+"))
  150. {
  151. MessageBox.Show("This function does not support multiple samples!");
  152. result = m_ReportApp.m_rstDataMgr.ResultFilesList[0];
  153. }
  154. else
  155. {
  156. result = m_ReportApp.m_rstDataMgr.ResultFilesList[m_ReportApp.m_conditionChoose.m_conditionData.GetComboDownListIndexByItemName(OTSIncAReportApp.OTSSampleReportInfo.OTS_REPORT_PROP_GRID_ITEMS.DATA_SOURCE)];
  157. }
  158. ReportFun = new OTSImageDisHelp(result);
  159. //设置窗体的双缓冲,以保证大数据时拖动不卡
  160. this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
  161. this.UpdateStyles();
  162. InitializeComponent();
  163. //利用反射设置DataGridView的双缓冲
  164. Type dgvType = this.dgV_ParticlesDevidePage.GetType();
  165. PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
  166. pi?.SetValue(this.dgV_ParticlesDevidePage, true, null);
  167. this.control_XRayTable1 = new Control_XRayTable(null);
  168. this.control_XRayTable1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
  169. this.control_XRayTable1.Dock = System.Windows.Forms.DockStyle.Bottom;
  170. this.control_XRayTable1.GBInfoStr = "";
  171. this.control_XRayTable1.GoodChineseName = "";
  172. this.control_XRayTable1.MaterialName = "";
  173. this.control_XRayTable1.Location = new System.Drawing.Point(0, 400);
  174. this.control_XRayTable1.Name = "control_XRayTable1";
  175. this.control_XRayTable1.ShowAnalysisXray = true;
  176. this.control_XRayTable1.ShowSearchXray = false;
  177. this.control_XRayTable1.Size = new System.Drawing.Size(1004, 200);
  178. this.control_XRayTable1.STDName = "";
  179. this.control_XRayTable1.Visible = false;
  180. this.control_XRayTable1.label_close.Visible = true;
  181. this.Controls.Add(this.control_XRayTable1);
  182. }
  183. private bool Init()
  184. {
  185. if (result == null)
  186. {
  187. return false;
  188. }
  189. try
  190. {
  191. lan = new Language(this);
  192. table = lan.GetNameTable(this.Name);
  193. m_mythread_state = false;
  194. m_mythread = new Thread(new ParameterizedThreadStart(ControlThread_GO));
  195. fieldData = new FieldData(result.FilePath);
  196. Particledata = new ParticleData(result.FilePath);
  197. fldImgAccess = new FieldAndParticleImage(result.FilePath);
  198. var systype = m_ReportApp.m_RptConfigFile.Systype;
  199. if (systype == OTS_SysType_ID.TCCleannessA || systype == OTS_SysType_ID.BatteryCleannessA)
  200. {
  201. string str_STDDbName = result.GetSTDName();
  202. userSTDDb = new UserSTDDbAccess(str_STDDbName, result.FilePath + "\\");
  203. userSTDDbData = userSTDDb.GetSqlHelper() != null ?
  204. userSTDDb.GetSubAttributeFromDatabase() : null;
  205. }
  206. //初始化底层操作类
  207. m_OTSIncAReportGridsFun = new SEMAndEDSOperate();
  208. return true;
  209. }
  210. catch (Exception ex)
  211. {
  212. log.Error(ex.ToString());
  213. return false;
  214. }
  215. }
  216. private void ParticlesGridDevidePage_Load(object sender, EventArgs e)
  217. {
  218. if (!Init())
  219. {
  220. return;
  221. }
  222. ProgressStart();
  223. if (!UpdateDataGrid())
  224. {
  225. return;
  226. }
  227. InitializePageSizeComboBox();
  228. InitializeTypeTextBox();
  229. dgV_ParticlesDevidePage.Focus();
  230. }
  231. private Dictionary<string, string> InitializeTable(ref string str_ElementsColName)
  232. {
  233. dgV_ParticlesDevidePage.Rows.Clear();
  234. dgV_ParticlesDevidePage.Columns.Clear();
  235. var startFun = m_ReportApp.m_RptConfigFile.Systype;
  236. string str_DefaultComputedColName = ""; str_ElementsColName = "";
  237. DataSet ds = XMLoperate.GetXmlData(Application.StartupPath + RptConfigFile.m_ReportMgrParamFile, "XMLData"); DataTable dt = ds.Tables["Member"];
  238. foreach (DataRow element in dt.Rows)
  239. {
  240. string regName = element["RegName"].ToString();
  241. if (regName == "DefaultComputedColName")
  242. {
  243. str_DefaultComputedColName = element["strValue"].ToString();
  244. }
  245. else if (regName == "ElementsColName")
  246. {
  247. str_ElementsColName = element["strValue"].ToString();
  248. }
  249. }
  250. string[] strs = str_DefaultComputedColName.Split(',');
  251. var keyValues = new Dictionary<string, string>
  252. {
  253. ["rowid"] = table["str4"].ToString(),
  254. ["TypeName"] = table["str6"].ToString()
  255. };
  256. foreach (string str in strs)
  257. {
  258. switch (str)
  259. {
  260. case "ParticleImage":
  261. keyValues["ParticleImage"] = table["str5"].ToString();
  262. break;
  263. case "FieldId":
  264. keyValues["FieldId"] = table["str38"].ToString();
  265. break;
  266. case "ParticleId":
  267. keyValues["ParticleId"] = table["str39"].ToString();
  268. break;
  269. case "FieldPos":
  270. keyValues["SEMPosX"] = table["str19"].ToString();
  271. keyValues["SEMPosY"] = table["str20"].ToString();
  272. break;
  273. case "ParticleCoordinate":
  274. keyValues["AbPosX"] = "颗粒X轴坐标";
  275. keyValues["AbPosY"] = "颗粒Y轴坐标"; break;
  276. case "Area":
  277. keyValues["Area"] = table["str21"].ToString();
  278. break;
  279. case "EquivalentCircleDiameter":
  280. keyValues["Equivalent"] = table["str22"].ToString();
  281. break;
  282. case "MaxDiameter":
  283. keyValues["DMAX"] = table["str23"].ToString();
  284. break;
  285. case "MinDiameter":
  286. keyValues["DMIN"] = table["str24"].ToString();
  287. break;
  288. case "DiameterRatio":
  289. keyValues["DiameterRatio"] = table["str25"].ToString(); break;
  290. case "FerretDiameter":
  291. keyValues["DFERET"] = table["str26"].ToString();
  292. break;
  293. case "PERP":
  294. keyValues["DPERP"] = table["str27"].ToString();
  295. break;
  296. case "PERI":
  297. keyValues["PERIMETER"] = table["str28"].ToString();
  298. break;
  299. case "INSCR":
  300. keyValues["DINSCR"] = table["str29"].ToString();
  301. break;
  302. case "MEAN":
  303. keyValues["DMEAN"] = table["str30"].ToString();
  304. break;
  305. case "ELONG":
  306. keyValues["DELONG"] = table["str31"].ToString();
  307. break;
  308. case "ASPECT_ELONG":
  309. keyValues["ASPECT_ELONG"] = table["str32"].ToString();
  310. break;
  311. case "Orientation":
  312. keyValues["ORIENTATION"] = table["str33"].ToString();
  313. break;
  314. case "XRayDataCount":
  315. keyValues["XRayDataCount"] = table["str37"].ToString();
  316. break;
  317. }
  318. if (startFun == OTS_SysType_ID.TCCleannessA || startFun == OTS_SysType_ID.BatteryCleannessA)
  319. {
  320. switch (str)
  321. {
  322. case "Hardness":
  323. keyValues["Hardness"] = table["str34"].ToString();
  324. break;
  325. case "Density":
  326. keyValues["Density"] = table["str35"].ToString();
  327. break;
  328. case "Electrical_conductivity":
  329. keyValues["Electrical_conductivity"] = table["str36"].ToString();
  330. break;
  331. }
  332. }
  333. }
  334. keyValues["Element"] = "Element";
  335. return keyValues;
  336. }
  337. private void InitializePageSizeComboBox()
  338. {
  339. cbB_PageSize.Items.AddRange(new object[] { "20", "100", "500", "1000", "5000", "All" });
  340. cbB_PageSize.SelectedIndex = 0;
  341. }
  342. private void InitializeTypeTextBox()
  343. {
  344. DataTable classificationTable = GetClassificationOfAllParticles();
  345. if (classificationTable?.Rows.Count > 0)
  346. {
  347. tbx_Type.Text = string.Join("$", classificationTable.AsEnumerable()
  348. .Select(row => row["TypeName"].ToString()));
  349. }
  350. }
  351. // 新增:为 userSTDDbData 建立索引以加速查找
  352. private Dictionary<string, DataRow> BuildUserStdLookup()
  353. {
  354. var dict = new Dictionary<string, DataRow>();
  355. if (userSTDDbData == null)
  356. return dict;
  357. foreach (DataRow r in userSTDDbData.Rows)
  358. {
  359. var key = Convert.ToString(r["STDId"]);
  360. if (!dict.ContainsKey(key))
  361. dict.Add(key, r);
  362. }
  363. return dict;
  364. }
  365. private void InitializeGridViewColumns(Dictionary<string, string> keyValues)
  366. {
  367. dgV_ParticlesDevidePage.Rows.Clear();
  368. dgV_ParticlesDevidePage.Columns.Clear();
  369. foreach (var kvp in keyValues)
  370. {
  371. if (kvp.Key == "ParticleImage")
  372. {
  373. var iconColumn = new DataGridViewImageColumn
  374. {
  375. Name = kvp.Key,
  376. HeaderText = kvp.Value
  377. };
  378. dgV_ParticlesDevidePage.Columns.Add(iconColumn);
  379. }
  380. else if (kvp.Key != "Element")
  381. {
  382. dgV_ParticlesDevidePage.Columns.Add(kvp.Key, kvp.Value);
  383. if (IsNumericColumn(kvp.Key))
  384. {
  385. int id = dgV_ParticlesDevidePage.Columns.Count;
  386. dgV_ParticlesDevidePage.Columns[id - 1].Tag = "NumericType";
  387. }
  388. }
  389. }
  390. }
  391. #endregion
  392. #region 数据加载
  393. private DataTable GetParticleDataBySelection(int selection)
  394. {
  395. switch (selection)
  396. {
  397. case (int)SelItem.analyticalParticle:
  398. return Particledata.GetInfoForPartucleDevidePage_analyticalParticle(condition);
  399. case (int)SelItem.otherParticles:
  400. return Particledata.GetInfoForPartucleDevidePage_otherParticle(condition);
  401. case (int)SelItem.MergeParticles:
  402. return Particledata.GetInfoForPartucleDevidePage_mergeParticles(condition);
  403. case (int)SelItem.allParticles:
  404. return Particledata.GetInfoForPartucleDevidePage_allParticles(condition);
  405. default:
  406. return new DataTable();
  407. }
  408. }
  409. private bool UpdateDataGrid()
  410. {
  411. int sel = m_ReportApp.m_conditionChoose.m_conditionData
  412. .GetComboDownListIndexByItemName(OTSIncAReportApp.OTSSampleReportInfo.OTS_REPORT_PROP_GRID_ITEMS.PARTICE_LIST);
  413. particlesAll = GetParticleDataBySelection(sel);
  414. if (particlesAll == null)
  415. {
  416. log.Error("There is an exception in the data of the database!");
  417. CloseProgressIfNeeded();
  418. return false;
  419. }
  420. // 添加必要列
  421. particlesAll.Columns.Add("Hardness");
  422. particlesAll.Columns.Add("Density");
  423. particlesAll.Columns.Add("Electrical_conductivity");
  424. // 使用字典索引 userSTDDbData,避免对每行使用 DataTable.Select(性能瓶颈)
  425. var userStdLookup = BuildUserStdLookup();
  426. UpdateHardnessDensityData(userStdLookup);
  427. btn_Sel.Enabled = true;
  428. DataTable elementchemistry = Particledata.GetElementChemistry();
  429. var elemIndex = BuildElementChemistryIndex(elementchemistry);
  430. UpdateElementData(elemIndex);
  431. particlesAll.Columns.Add("XRayDataCount");
  432. DataTable XRayData = Particledata.GetXRayData();
  433. var xrayIndex = BuildXRayDataIndex(XRayData);
  434. UpdateXRayDataCount(xrayIndex);
  435. return true;
  436. }
  437. private void UpdateHardnessDensityData(Dictionary<string, DataRow> userStdLookup)
  438. {
  439. string emptyValue = "";
  440. for (int i = 0; i < particlesAll.Rows.Count; i++)
  441. {
  442. string key = Convert.ToString(particlesAll.Rows[i]["TypeId"]);
  443. if (userSTDDbData != null && userStdLookup.TryGetValue(key, out var dr))
  444. {
  445. particlesAll.Rows[i]["Hardness"] = dr["Hardness"].ToString();
  446. particlesAll.Rows[i]["Density"] = dr["Density"].ToString();
  447. particlesAll.Rows[i]["Electrical_conductivity"] = dr["Electrical_conductivity"].ToString();
  448. }
  449. else
  450. {
  451. particlesAll.Rows[i]["Hardness"] = emptyValue;
  452. particlesAll.Rows[i]["Density"] = emptyValue;
  453. particlesAll.Rows[i]["Electrical_conductivity"] = emptyValue;
  454. }
  455. }
  456. }
  457. private Dictionary<string, List<DataRow>> BuildElementChemistryIndex(DataTable elementchemistry)
  458. {
  459. var elemIndex = new Dictionary<string, List<DataRow>>();
  460. foreach (DataRow er in elementchemistry.Rows)
  461. {
  462. string key = $"XRayId = {er["XRayId"]} and fieldid = {er["fieldid"]}";
  463. if (!elemIndex.TryGetValue(key, out var list))
  464. {
  465. list = new List<DataRow>();
  466. elemIndex[key] = list;
  467. }
  468. list.Add(er);
  469. }
  470. return elemIndex;
  471. }
  472. private void UpdateElementData(Dictionary<string, List<DataRow>> elemIndex)
  473. {
  474. for (int i = 0; i < particlesAll.Rows.Count; i++)
  475. {
  476. string key = $"XRayId = {particlesAll.Rows[i]["particleId"]} and fieldid = {particlesAll.Rows[i]["fieldid"]}";
  477. string concatenatedString = "";
  478. if (elemIndex.TryGetValue(key, out var drList))
  479. {
  480. concatenatedString = string.Join(";", drList.Select(dr => $"{dr["name"]}-{dr["Percentage"]}"));
  481. }
  482. particlesAll.Rows[i]["Element"] = concatenatedString;
  483. }
  484. }
  485. private Dictionary<string, byte[]> BuildXRayDataIndex(DataTable XRayData)
  486. {
  487. var xrayIndex = new Dictionary<string, byte[]>();
  488. foreach (DataRow xr in XRayData.Rows)
  489. {
  490. if (xr.ItemArray.Length >= 3 && xr[2] is byte[] b)
  491. {
  492. string key = $" XrayIndex= {xr[0]} and fieldid = {xr[1]}";
  493. if (!xrayIndex.ContainsKey(key))
  494. {
  495. xrayIndex[key] = b;
  496. }
  497. }
  498. }
  499. return xrayIndex;
  500. }
  501. private void UpdateXRayDataCount(Dictionary<string, byte[]> xrayIndex)
  502. {
  503. for (int i = 0; i < particlesAll.Rows.Count; i++)
  504. {
  505. string subParticleString = Convert.ToString(particlesAll.Rows[i]["SubParticles"]);
  506. if (string.IsNullOrEmpty(subParticleString))
  507. {
  508. particlesAll.Rows[i]["XRayDataCount"] = 0;
  509. string str = $" XrayIndex= {particlesAll.Rows[i]["particleId"]} and fieldid = {particlesAll.Rows[i]["fieldid"]}";
  510. if (xrayIndex.TryGetValue(str, out var bytes))
  511. {
  512. uint xraycount = 0;
  513. int len = bytes.Length / 4;
  514. for (int j = 0; j < len; j++)
  515. {
  516. xraycount += BitConverter.ToUInt32(bytes, j * 4);
  517. }
  518. particlesAll.Rows[i]["XRayDataCount"] = xraycount;
  519. }
  520. }
  521. else
  522. {
  523. particlesAll.Rows[i]["XRayDataCount"] = 0;
  524. DataRow dgvr = particlesAll.Rows[i];
  525. uint[] Analysis_xray = new uint[2000];
  526. Particledata.GetXrayByParticleTagIDAndFieldID_ForMergeParticle(
  527. Convert.ToInt32(dgvr["particleId"]),
  528. Convert.ToInt32(dgvr["fieldid"]),
  529. out Analysis_xray);
  530. uint xraycount = 0;
  531. for (int j = 0; j < Analysis_xray.Length; j++)
  532. {
  533. xraycount += Analysis_xray[j];
  534. }
  535. particlesAll.Rows[i]["XRayDataCount"] = xraycount;
  536. }
  537. }
  538. }
  539. private void RefreshGridView()
  540. {
  541. dgV_ParticlesDevidePage.Visible = false;
  542. if (m_frm_userprogress == null || m_frm_userprogress.IsDisposed)
  543. {
  544. ProgressStart();
  545. }
  546. string str_ElementsColName = null;
  547. Dictionary<string, string> keyValues = InitializeTable(ref str_ElementsColName);
  548. // 减少 UI 重绘开销
  549. dgV_ParticlesDevidePage.SuspendLayout();
  550. try
  551. {
  552. InitializeGridViewColumns(keyValues);
  553. if (PageSize <= 0)
  554. {
  555. PageSize = particlesAll?.Rows.Count ?? 0;
  556. }
  557. if (particlesAll == null)
  558. {
  559. return;
  560. }
  561. UpdatePageData();
  562. InitializeElementColumns(str_ElementsColName);
  563. LoadParticleData(keyValues);
  564. }
  565. finally
  566. {
  567. dgV_ParticlesDevidePage.ResumeLayout();
  568. dgV_ParticlesDevidePage.Visible = true;
  569. CloseProgress();
  570. }
  571. }
  572. private void UpdatePageData()
  573. {
  574. RecordCount = particlesAll.Rows.Count;
  575. particlesFilter = particlesAll.Clone();
  576. int startRow = (PageIndex - 1) * pageSize;
  577. int endRow = Math.Min(startRow + pageSize, RecordCount);
  578. for (int fi = startRow; fi < endRow; fi++)
  579. {
  580. particlesFilter.ImportRow(particlesAll.Rows[fi]);
  581. }
  582. }
  583. private void InitializeElementColumns(string str_ElementsColName)
  584. {
  585. elementTypeSort = string.IsNullOrEmpty(str_ElementsColName) ?
  586. new List<string>() :
  587. str_ElementsColName.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
  588. .Distinct()
  589. .ToList();
  590. foreach (string element in elementTypeSort)
  591. {
  592. dgV_ParticlesDevidePage.Columns.Add(element, element);
  593. int id = dgV_ParticlesDevidePage.Columns.Count;
  594. dgV_ParticlesDevidePage.Columns[id - 1].Tag = "NumericType";
  595. }
  596. }
  597. private void LoadParticleData(Dictionary<string, string> keyValues)
  598. {
  599. if (particlesFilter?.Rows.Count == 0) return;
  600. double progressStep = particlesFilter.Rows.Count > 0 ? 95.0 / particlesFilter.Rows.Count : 95.0;
  601. string filePath = Path.Combine(result.FilePath, "FIELD_FILES");
  602. // 把 fieldpics 缓存提升到循环外,避免对同一 field 多次磁盘读取
  603. var fieldPics = new Dictionary<string, Bitmap>(StringComparer.OrdinalIgnoreCase);
  604. for (int i = 0; i < particlesFilter.Rows.Count; i++)
  605. {
  606. if (i % 10 == 0 && m_frm_userprogress != null && !m_frm_userprogress.IsDisposed)
  607. m_frm_userprogress.SetProgressValueAndText((int)(progressStep * i), "loading..");
  608. int add_rowindex = dgV_ParticlesDevidePage.Rows.Add();
  609. dgV_ParticlesDevidePage.Rows[add_rowindex].Cells[0].Value =
  610. (pageSize * (PageIndex - 1) + add_rowindex + 1).ToString();
  611. LoadParticleRowData(i, add_rowindex, keyValues, fieldPics);
  612. }
  613. }
  614. private void ProcessColumnData(int rowIndex, int gridRowIndex, int columnIndex, string columnName, Dictionary<string, Bitmap> fieldPics)
  615. {
  616. switch (columnName)
  617. {
  618. case "ParticleImage":
  619. ProcessParticleImageColumn(rowIndex, gridRowIndex, columnIndex, fieldPics);
  620. break;
  621. case "DiameterRatio":
  622. ProcessDiameterRatioColumn(rowIndex, gridRowIndex, columnIndex);
  623. break;
  624. case "ASPECT_ELONG":
  625. ProcessAspectElongColumn(rowIndex, gridRowIndex, columnIndex);
  626. break;
  627. case "Element":
  628. ProcessElementColumn(rowIndex, gridRowIndex);
  629. break;
  630. case "TypeName":
  631. ProcessTypeNameColumn(rowIndex, gridRowIndex, columnIndex);
  632. break;
  633. case "Equivalent":
  634. ProcessEquivalentColumn(rowIndex, gridRowIndex, columnIndex);
  635. break;
  636. case "Hardness":
  637. ProcessHardnessColumn(rowIndex, gridRowIndex, columnIndex);
  638. break;
  639. case "AbPosX":
  640. ProcessAbPosColumn(rowIndex, gridRowIndex);
  641. break;
  642. default:
  643. break;
  644. }
  645. AdjustTheFormatOfTheUnitValues(rowIndex, gridRowIndex, columnIndex, columnName);
  646. }
  647. private void ProcessParticleImageColumn(int rowIndex, int gridRowIndex, int columnIndex, Dictionary<string, Bitmap> fieldPics)
  648. {
  649. string subParticleString = Convert.ToString(particlesFilter.Rows[rowIndex]["SubParticles"]);
  650. dgV_ParticlesDevidePage.Rows[gridRowIndex].Height = 70;
  651. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Style.BackColor = Color.Azure;
  652. Bitmap bmap = null;
  653. if (!string.IsNullOrEmpty(subParticleString) && subParticleString != "IsSubParticle")
  654. {
  655. bmap = CreateMergedParticleImage(subParticleString);
  656. }
  657. else if (subParticleString != "IsSubParticle")
  658. {
  659. bmap = CreateSingleParticleImage(rowIndex, fieldPics);
  660. }
  661. bmap.Tag = new List<string>() { particlesFilter.Rows[rowIndex]["fieldid"].ToString(), particlesFilter.Rows[rowIndex]["ParticleId"].ToString() };
  662. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = bmap;
  663. }
  664. private void LoadParticleRowData(int rowIndex, int gridRowIndex, Dictionary<string, string> keyValues, Dictionary<string, Bitmap> fieldPics)
  665. {
  666. foreach (var kvp in keyValues)
  667. {
  668. int columnIndex = dgV_ParticlesDevidePage.Columns.IndexOf(dgV_ParticlesDevidePage.Columns[kvp.Key]);
  669. //if (columnIndex < 0) continue;
  670. ProcessColumnData(rowIndex, gridRowIndex, columnIndex, kvp.Key, fieldPics);
  671. }
  672. }
  673. private void ProcessElementColumn(int rowIndex, int gridRowIndex)
  674. {
  675. List<string> elementtemp = new List<string>(elementTypeSort);
  676. string[] strcbo = particlesFilter.Rows[rowIndex]["Element"].ToString().Split(';');
  677. for (int j = 0; j < strcbo.Length; j++)
  678. {
  679. if (elementTypeSort.Count == 0)
  680. {
  681. break;
  682. }
  683. string[] str = strcbo[j].Split('-');
  684. if (elementTypeSort.Contains(str[0]))
  685. { dgV_ParticlesDevidePage.Rows[rowIndex].Cells[str[0].ToString()].Value = Math.Round(double.Parse(str[1]), 2).ToString(); }
  686. elementtemp.Remove(str[0].ToString());
  687. }
  688. foreach (var ele in elementtemp)
  689. {
  690. dgV_ParticlesDevidePage.Rows[rowIndex].Cells[ele].Value = "0";
  691. }
  692. }
  693. private void ProcessTypeNameColumn(int rowIndex, int gridRowIndex, int columnIndex)
  694. {
  695. if (particlesFilter.Rows[rowIndex]["TypeId"].ToString() == "9")
  696. {
  697. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = "Not Identified";
  698. }
  699. }
  700. private void ProcessEquivalentColumn(int rowIndex, int gridRowIndex, int columnIndex)
  701. {
  702. double dSize = Convert.ToDouble(particlesFilter.Rows[rowIndex]["Area"]);
  703. double diameter = Math.Sqrt(dSize / Math.PI) * 2;
  704. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = Math.Round(diameter, 2);
  705. }
  706. private void ProcessHardnessColumn(int rowIndex, int gridRowIndex, int columnIndex)
  707. {
  708. string hardnessColor = ChangeHardnessColor(Convert.ToString(particlesFilter.Rows[rowIndex]["Hardness"]));
  709. if (hardnessColor == "#FF0000")
  710. {
  711. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Style.ForeColor = Color.Red;
  712. }
  713. }
  714. private void ProcessAbPosColumn(int rowIndex, int gridRowIndex)
  715. {
  716. Point semPos = new Point(
  717. Convert.ToInt32(particlesFilter.Rows[rowIndex]["SEMPosX"]),
  718. Convert.ToInt32(particlesFilter.Rows[rowIndex]["SEMPosY"]));
  719. Point particlePos = new Point(
  720. Convert.ToInt32(particlesFilter.Rows[rowIndex]["PosX"]),
  721. Convert.ToInt32(particlesFilter.Rows[rowIndex]["PosY"]));
  722. Point point = CalculateParticleCenterPosition(result, semPos, particlePos);
  723. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells["AbPosX"].Value = point.X;
  724. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells["AbPosY"].Value = point.Y;
  725. }
  726. private void ProcessDiameterRatioColumn(int rowIndex, int gridRowIndex, int columnIndex)
  727. {
  728. double dmax = Convert.ToDouble(particlesFilter.Rows[rowIndex]["DMAX"]);
  729. double dmin = Convert.ToDouble(particlesFilter.Rows[rowIndex]["DMIN"]);
  730. double ratio = dmin != 0 ? dmax / dmin : 0;
  731. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = Math.Round(ratio, 2);
  732. }
  733. private void ProcessAspectElongColumn(int rowIndex, int gridRowIndex, int columnIndex)
  734. {
  735. double delong = Convert.ToDouble(particlesFilter.Rows[rowIndex]["DELONG"]);
  736. double dmean = Convert.ToDouble(particlesFilter.Rows[rowIndex]["DMEAN"]);
  737. double ratio = dmean != 0 ? delong / dmean : 0;
  738. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = Math.Round(ratio, 2);
  739. }
  740. /// <summary>
  741. /// 页面控件呈现
  742. /// </summary>
  743. private void DrawControl(bool callEvent)
  744. {
  745. RefreshGridView();
  746. lblTotalCount.Text = RecordCount.ToString();
  747. lblPageCount.Text = PageCount.ToString();
  748. txtPageNum.Text = PageIndex.ToString();
  749. SetFormCtrEnabled();
  750. if (PageCount == 0 || PageCount == 1) //有且仅有一页
  751. {
  752. lnkFirst.Enabled = false;
  753. lnkPrev.Enabled = false;
  754. lnkNext.Enabled = false;
  755. lnkLast.Enabled = false;
  756. btnGo.Enabled = false;
  757. }
  758. else if (PageIndex == 1) //第一页
  759. {
  760. lnkFirst.Enabled = false;
  761. lnkPrev.Enabled = false;
  762. }
  763. else if (PageIndex == PageCount) //最后一页
  764. {
  765. lnkNext.Enabled = false;
  766. lnkLast.Enabled = false;
  767. }
  768. }
  769. private void DisplayData()
  770. {
  771. if (cbB_PageSize.SelectedItem?.ToString() == "All"){pageSize = -1;}
  772. else if (int.TryParse(cbB_PageSize.SelectedItem?.ToString(), out int parsedSize)){pageSize = parsedSize;}
  773. lnkFirst_Click(null, null);
  774. SetDataGridViewStyle();
  775. }
  776. #endregion
  777. #region 健壮性判断
  778. private bool IsNumericColumn(string columnName)
  779. {
  780. string[] numericColumns = {
  781. "Area", "EquivalentCircleDiameter", "MaxDiameter", "MinDiameter",
  782. "DiameterRatio", "FerretDiameter", "PERP", "PERI", "INSCR",
  783. "MEAN", "ELONG", "ASPECT_ELONG", "Orientation"
  784. };
  785. return numericColumns.Contains(columnName);
  786. }
  787. /// <summary>
  788. /// 判断条件输入 前<后
  789. /// </summary>
  790. /// <param name="min"></param>
  791. /// <param name="max"></param>
  792. /// <returns></returns>
  793. private bool CompareInput(string min, string max)
  794. {
  795. if (!double.TryParse(max, out double dmax))
  796. {
  797. if (!int.TryParse(max, out int imax))
  798. return false;
  799. dmax = imax;
  800. }
  801. if (!double.TryParse(min, out double dmin))
  802. {
  803. if (!int.TryParse(min, out int imin))
  804. return false;
  805. dmin = imin;
  806. }
  807. return dmin <= dmax;
  808. }
  809. private bool ValidateAndAddCondition(string value, string fieldName, string operatorSymbol)
  810. {
  811. if (string.IsNullOrWhiteSpace(value)) return true;
  812. if (double.TryParse(value, out double dnum) && dnum >= 0)
  813. {
  814. condition += $" and {fieldName} {operatorSymbol} {value}";
  815. return true;
  816. }
  817. if (int.TryParse(value, out int inum) && inum >= 0)
  818. {
  819. condition += $" and {fieldName} {operatorSymbol} {value}";
  820. return true;
  821. }
  822. ShowErrorMessage("str10");
  823. return false;
  824. }
  825. private bool ValidateIntegerField(string value, string fieldName)
  826. {
  827. if (string.IsNullOrWhiteSpace(value)) return true;
  828. if (int.TryParse(value, out _))
  829. {
  830. condition += $" and {fieldName} = {value}";
  831. return true;
  832. }
  833. ShowErrorMessage("str10");
  834. return false;
  835. }
  836. private bool ProcessECDConditions()
  837. {
  838. if (!string.IsNullOrWhiteSpace(tbx_ECDMin.Text))
  839. {
  840. if (double.TryParse(tbx_ECDMin.Text, out double dnum) && dnum >= 0)
  841. {
  842. double area = Math.PI * dnum / 2 * dnum / 2;
  843. condition += $" and Area > {area}";
  844. }
  845. else if (int.TryParse(tbx_ECDMin.Text, out int inum) && inum >= 0)
  846. {
  847. double area = Math.PI * inum / 2 * inum / 2;
  848. condition += $" and Area > {area}";
  849. }
  850. else
  851. {
  852. ShowErrorMessage("str10");
  853. return false;
  854. }
  855. }
  856. if (!string.IsNullOrWhiteSpace(tbx_ECDMax.Text))
  857. {
  858. if (double.TryParse(tbx_ECDMax.Text, out double dnum) && dnum >= 0)
  859. {
  860. double area = Math.PI * dnum / 2 * dnum / 2;
  861. condition += $" and Area < {area}";
  862. }
  863. else if (int.TryParse(tbx_ECDMax.Text, out int inum) && inum >= 0)
  864. {
  865. double area = Math.PI * inum / 2 * inum / 2;
  866. condition += $" and Area < {area}";
  867. }
  868. else
  869. {
  870. ShowErrorMessage("str10");
  871. return false;
  872. }
  873. }
  874. if (!string.IsNullOrWhiteSpace(tbx_ECDMin.Text) &&
  875. !string.IsNullOrWhiteSpace(tbx_ECDMax.Text))
  876. {
  877. if (!CompareInput(tbx_ECDMin.Text, tbx_ECDMax.Text))
  878. {
  879. ShowErrorMessage("str11");
  880. return false;
  881. }
  882. }
  883. return true;
  884. }
  885. private void ShowErrorMessage(string resourceKey)
  886. {
  887. MessageBox.Show(table?[resourceKey].ToString() ?? "输入错误");
  888. }
  889. #endregion
  890. #region 数据处理
  891. private Bitmap CreateMergedParticleImage(string subParticleString)
  892. {
  893. double pix = result.GetPixelSize();
  894. int width = result.GetImageWidth();
  895. int height = result.GetImageHeight();
  896. string vs = "," + subParticleString.Replace(':', '-') + ",";
  897. DataTable dataTable = Particledata.GetParticleAllForBig(vs);
  898. var bmap1 = fldImgAccess.GetBitmapForMergedParticle(subParticleString, pix, height, width, dataTable);
  899. int cellWidth = dgV_ParticlesDevidePage.Columns["ParticleImage"].Width - 20;
  900. int cellHeight = dgV_ParticlesDevidePage.Rows[0].Height - 20;
  901. var ratioX = (double)cellWidth / bmap1.Width;
  902. var ratioY = (double)cellWidth / bmap1.Height;
  903. var ratio = Math.Min(ratioX, ratioY);
  904. var bmap = fldImgAccess.ScaleImageProportional(bmap1, ratio);
  905. return bmap;
  906. }
  907. private Bitmap CreateSingleParticleImage(int rowIndex, Dictionary<string, Bitmap> fieldPics)
  908. {
  909. string fid = Convert.ToString(particlesFilter.Rows[rowIndex]["fieldid"]);
  910. if (!fieldPics.ContainsKey(fid))
  911. {
  912. string imagePath = "Field" + fid + ".bmp";
  913. fieldPics[fid] = fldImgAccess.ReadImageFile(imagePath);
  914. }
  915. Rectangle rectangle = new Rectangle()
  916. {
  917. X = Convert.ToInt32(particlesFilter.Rows[rowIndex]["RectLeft"]),
  918. Y = Convert.ToInt32(particlesFilter.Rows[rowIndex]["RectTop"]),
  919. Width = Convert.ToInt32(particlesFilter.Rows[rowIndex]["RectWidth"]),
  920. Height = Convert.ToInt32(particlesFilter.Rows[rowIndex]["RectHeight"])
  921. };
  922. var src = fieldPics[fid];
  923. if (src != null)
  924. {
  925. var bmap1 = fldImgAccess.CapturePic(src, rectangle);
  926. int cellWidth = dgV_ParticlesDevidePage.Columns["ParticleImage"].Width - 20;
  927. int cellHeight = dgV_ParticlesDevidePage.Rows[0].Height - 20;
  928. var ratioX = (double)cellWidth / bmap1.Width;
  929. var ratioY = (double)cellWidth / bmap1.Height;
  930. var ratio = Math.Min(ratioX, ratioY);
  931. var bmap = fldImgAccess.ScaleImageProportional(bmap1, ratio);
  932. return bmap;
  933. }
  934. return null;
  935. }
  936. /// <summary>
  937. /// 计算颗粒中心的电镜坐标
  938. /// </summary>
  939. /// <param name="resultFile"></param>
  940. /// <param name="SEMPos"></param>
  941. /// <param name="ParticlePos"></param>
  942. /// <returns></returns>
  943. public static Point CalculateParticleCenterPosition(ResultFile resultFile, Point SEMPos, Point ParticlePos)
  944. {
  945. Point point = new Point();
  946. float scanFieldSizeX = resultFile.GetScanFieldSizeX();
  947. string leftOrRight = resultFile.GetXAxisDir();
  948. string downOrUp = resultFile.GetYAxisDir();
  949. float scanFieldSizeY = resultFile.GetScanFieldSizeY();
  950. float pixelSize = resultFile.GetPixelSize();
  951. if (leftOrRight == "RIGHT_TOWARD")
  952. {
  953. point.X = (int)(SEMPos.X - scanFieldSizeX / 2 + ParticlePos.X * pixelSize);
  954. }
  955. else
  956. {
  957. point.X = (int)(SEMPos.X + scanFieldSizeX / 2 - ParticlePos.X * pixelSize);
  958. }
  959. if (downOrUp == "UP_TOWARD")
  960. {
  961. point.Y = (int)(SEMPos.Y + scanFieldSizeY / 2 - ParticlePos.Y * pixelSize);
  962. }
  963. else
  964. {
  965. point.Y = (int)(SEMPos.Y - scanFieldSizeY / 2 + ParticlePos.Y * pixelSize);
  966. }
  967. return point;
  968. }
  969. /// <summary>
  970. /// 复制选择区域
  971. /// </summary>
  972. public void CopySelected()
  973. {
  974. //复制选择区域
  975. object clipboardContent = dgV_ParticlesDevidePage.GetClipboardContent();
  976. if (clipboardContent != null)
  977. Clipboard.SetDataObject(dgV_ParticlesDevidePage.GetClipboardContent());
  978. }
  979. /// <summary>
  980. /// 复制所有
  981. /// </summary>
  982. public void CopyAll()
  983. {
  984. dgV_ParticlesDevidePage.SelectAll();
  985. Clipboard.SetDataObject(dgV_ParticlesDevidePage.GetClipboardContent());
  986. }
  987. /// <summary>
  988. /// 以图像的方式将GridView进行截图
  989. /// </summary>
  990. public void CopyImage()
  991. {
  992. int width = dgV_ParticlesDevidePage.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) + 2;
  993. int height = this.Height;
  994. using (Bitmap image = new Bitmap(width, height))
  995. {
  996. dgV_ParticlesDevidePage.DrawToBitmap(image, new Rectangle(0, 0, width, height));
  997. Clipboard.SetImage(image);
  998. }
  999. }
  1000. private void dgV_ParticlesDevidePage_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
  1001. {
  1002. //排序中
  1003. if (e.Column.Tag?.ToString() == "NumericType")
  1004. {
  1005. if (double.TryParse(e.CellValue1?.ToString(), out double val1) &&
  1006. double.TryParse(e.CellValue2?.ToString(), out double val2))
  1007. {
  1008. e.SortResult = val1.CompareTo(val2);
  1009. e.Handled = true;
  1010. }
  1011. }
  1012. }
  1013. private string ChangeHardnessColor(string hardness)
  1014. {
  1015. if (string.IsNullOrEmpty(hardness))
  1016. return "";
  1017. string str = System.Text.RegularExpressions.Regex.Replace(hardness, @"[^\d.\d]", "");
  1018. return double.TryParse(str, out double hd) && hd >= 1000 ? "#FF0000" : "";
  1019. }
  1020. private void SaveParticleslist_select()
  1021. {
  1022. ParticleData fielddata = new ParticleData(result.FilePath);
  1023. List<Particle> particles = fielddata.GetParticleAllList();
  1024. Particleslist_selecttodisplay.Clear();
  1025. for (int l = 0; l < dgV_ParticlesDevidePage.SelectedRows.Count; l++)
  1026. {
  1027. //从事先加载的Bitmap对象的Tag中取出List<string>
  1028. DataGridViewRow dgvr = dgV_ParticlesDevidePage.SelectedRows[l];
  1029. string str = " particleId= " + dgvr.Cells["particleId"].Value.ToString() + " and fieldid = " + dgvr.Cells["fieldid"].Value.ToString();
  1030. DataRow[] drs = particlesFilter.Select(str);
  1031. DataRow row = drs[0];
  1032. string subParticleString = row["SubParticles"].ToString();
  1033. int i_ls_fieldid = -1; int i_ls_particleid = -1;
  1034. if (subParticleString != "" && subParticleString != null)
  1035. {
  1036. string[] SubParticlesstrG = subParticleString.Split(',');
  1037. if (SubParticlesstrG.Length > 1)
  1038. {
  1039. string fieldid1 = SubParticlesstrG[0].Split(':')[0];
  1040. string pid1 = SubParticlesstrG[0].Split(':')[1];
  1041. i_ls_fieldid = Convert.ToInt32(fieldid1);
  1042. i_ls_particleid = Convert.ToInt32(pid1);
  1043. }
  1044. }
  1045. else
  1046. {
  1047. i_ls_fieldid = Convert.ToInt32(dgvr.Cells["particleId"].Value.ToString());
  1048. i_ls_particleid = Convert.ToInt32(dgvr.Cells["fieldid"].Value.ToString());
  1049. }
  1050. foreach (Particle item in particles)
  1051. {
  1052. if (i_ls_fieldid == item.FieldId && i_ls_particleid == item.ParticleId)
  1053. {
  1054. Particleslist_selecttodisplay.Add(item);
  1055. break;
  1056. }
  1057. }
  1058. }
  1059. }
  1060. public List<Particle> GetParticleslist_select()
  1061. {
  1062. return Particleslist_selecttodisplay;
  1063. }
  1064. /// <summary>
  1065. /// 获取所有颗粒的分类信息
  1066. /// </summary>
  1067. /// <returns></returns>
  1068. public DataTable GetClassificationOfAllParticles()
  1069. {
  1070. string str = "";
  1071. int sel = m_ReportApp.m_conditionChoose.m_conditionData.GetComboDownListIndexByItemName(OTSIncAReportApp.OTSSampleReportInfo.OTS_REPORT_PROP_GRID_ITEMS.PARTICE_LIST);
  1072. if (sel == (int)SelItem.analyticalParticle)
  1073. {
  1074. str = "where xrayid > -1 and typeid !=9 and typeid !=-1 and typeid !=4 and SubParticles is not 'IsSubParticle' ";
  1075. }
  1076. else if (sel == (int)SelItem.otherParticles)
  1077. {
  1078. str = "where SubParticles is not 'IsSubParticle'and(typeid =9 or typeid =-1 or typeid =4)";
  1079. }
  1080. else
  1081. {
  1082. }
  1083. DataTable table = Particledata.GetClassificationOfAllParticles(str);
  1084. return table;
  1085. }
  1086. #endregion
  1087. #region 格式处理
  1088. private void AdjustTheFormatOfTheUnitValues(int rowIndex, int gridRowIndex, int columnIndex, string columnName)
  1089. {
  1090. if (!particlesFilter.Columns.Contains(columnName)) return;
  1091. if (columnName== "Element") return;
  1092. var cellValue = particlesFilter.Rows[rowIndex][columnName];
  1093. if (cellValue == null) return;
  1094. if (double.TryParse(cellValue.ToString(), out double num))
  1095. {
  1096. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = Math.Round(num, 2);
  1097. }
  1098. else
  1099. {
  1100. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = cellValue.ToString();
  1101. }
  1102. }
  1103. private void SetFormCtrEnabled()
  1104. {
  1105. lnkFirst.Enabled = true;
  1106. lnkPrev.Enabled = true;
  1107. lnkNext.Enabled = true;
  1108. lnkLast.Enabled = true;
  1109. btnGo.Enabled = true;
  1110. }
  1111. /// <summary>
  1112. /// 设置DataGridView样式
  1113. /// </summary>
  1114. private void SetDataGridViewStyle()
  1115. {
  1116. //用户不能调整标题的高度
  1117. dgV_ParticlesDevidePage.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
  1118. //用户不能调整 行高
  1119. dgV_ParticlesDevidePage.AllowUserToResizeRows = false;
  1120. //点击选择整行
  1121. dgV_ParticlesDevidePage.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
  1122. //居中显示
  1123. DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle
  1124. {
  1125. Alignment = DataGridViewContentAlignment.MiddleCenter
  1126. };
  1127. dgV_ParticlesDevidePage.DefaultCellStyle = dataGridViewCellStyle1;
  1128. dgV_ParticlesDevidePage.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
  1129. //再次重覆禁用拖动表头高度,居然有效果了
  1130. dgV_ParticlesDevidePage.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
  1131. //设置grid可以复制
  1132. dgV_ParticlesDevidePage.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
  1133. //设置每列的宽度
  1134. if (dgV_ParticlesDevidePage.Columns.Count > 0)
  1135. {
  1136. dgV_ParticlesDevidePage.Columns[0].Width = 40; //第一列序号的宽度设置一下吧,要不太丑
  1137. if (dgV_ParticlesDevidePage.Columns.Count > 1)
  1138. dgV_ParticlesDevidePage.Columns[1].Width = 150;
  1139. }
  1140. //设置序号列不排序
  1141. if (dgV_ParticlesDevidePage.Columns.Count > 0)
  1142. {
  1143. dgV_ParticlesDevidePage.Columns[0].SortMode = DataGridViewColumnSortMode.NotSortable;
  1144. if (dgV_ParticlesDevidePage.Columns.Count > 1)
  1145. dgV_ParticlesDevidePage.Columns[1].SortMode = DataGridViewColumnSortMode.NotSortable;
  1146. }
  1147. //设置序号列不可以设置宽度
  1148. if (dgV_ParticlesDevidePage.Columns.Count > 0)
  1149. dgV_ParticlesDevidePage.Columns[0].Resizable = DataGridViewTriState.False;
  1150. dgV_ParticlesDevidePage.RowsDefaultCellStyle.BackColor = Color.Azure;
  1151. }
  1152. #endregion
  1153. #region 进度条
  1154. private void CloseProgress()
  1155. {
  1156. //加载完成设置鼠标为默认
  1157. this.Cursor = Cursors.Default;
  1158. string str8 = table?["str8"].ToString() ?? "完成";
  1159. if (m_frm_userprogress != null && !m_frm_userprogress.IsDisposed)
  1160. {
  1161. m_frm_userprogress.SetProgressValueAndText(100, str8);
  1162. m_frm_userprogress.Close();
  1163. }
  1164. }
  1165. private void CloseProgressIfNeeded()
  1166. {
  1167. this.Cursor = Cursors.Default;
  1168. if (m_frm_userprogress != null && !m_frm_userprogress.IsDisposed)
  1169. m_frm_userprogress.Close();
  1170. }
  1171. private void ProgressStart()
  1172. {
  1173. #region 加载显示进度条部份
  1174. this.Cursor = Cursors.WaitCursor;
  1175. m_frm_userprogress = new Frm_UserProgress();
  1176. Form ls_main_form = this.ParentForm?.ParentForm;//取出父窗体
  1177. if (ls_main_form == null)
  1178. {
  1179. m_frm_userprogress.Visible = false;
  1180. }
  1181. else
  1182. {
  1183. m_frm_userprogress.Width = (int)(MyPrimaryScreen.DESKTOP.Width / MyPrimaryScreen.ScaleX * 0.9);
  1184. m_frm_userprogress.Location = new Point(
  1185. ls_main_form.Location.X + 80,
  1186. ls_main_form.Location.Y + (int)(MyPrimaryScreen.DESKTOP.Height / MyPrimaryScreen.ScaleX) / 2);
  1187. m_frm_userprogress.Show();
  1188. m_frm_userprogress.SetProgressValueAndText(0, "Loading data of particles...");
  1189. }
  1190. #endregion
  1191. }
  1192. #endregion
  1193. #region UI事件
  1194. private void ToolStripMenuItem1_Click(object sender, EventArgs e)
  1195. {
  1196. //复制整个表
  1197. CopyAll();
  1198. }
  1199. private void ToolStripMenuItem2_Click(object sender, EventArgs e)
  1200. {
  1201. //复制选择区域
  1202. CopySelected();
  1203. }
  1204. private void toolStripMenuItem4_Click(object sender, EventArgs e)
  1205. {
  1206. //对gridview进行截图
  1207. CopyImage();
  1208. }
  1209. private void ToolStripMenuItem5_Click(object sender, EventArgs e)
  1210. {
  1211. /*注意:多数据源情况下,只获取第一个数据源的选择了多行的情况下,只获取最后一个选择行的,没有办法,这是为了符合李阳博士提出的要求*/
  1212. //先获取鼠标所选择的行里的颗粒的FieldID和ParticleID
  1213. if (dgV_ParticlesDevidePage.SelectedRows.Count == 0) return;
  1214. string i_ls_fieldid = "";
  1215. string i_ls_particleid = "";
  1216. int cou = dgV_ParticlesDevidePage.SelectedRows.Count;
  1217. DataGridViewRow dgvr = dgV_ParticlesDevidePage.SelectedRows[cou - 1];
  1218. if (dgvr.Cells[2].Value is Bitmap ls_bp && ls_bp.Tag is List<string> list_str)
  1219. {
  1220. i_ls_fieldid = list_str[0];
  1221. i_ls_particleid = list_str[1];
  1222. }
  1223. ParticleData particleData = new ParticleData(result.FilePath);
  1224. Particle particle = particleData.GetParticleByFidAndPid(i_ls_fieldid, i_ls_particleid);
  1225. //取得Field的Position,然后执行线程移动SEM到当前Field的位置
  1226. if (m_mythread == null) return;
  1227. if (m_mythread.ThreadState == ThreadState.Running ||
  1228. m_mythread.ThreadState == ThreadState.WaitSleepJoin)
  1229. {
  1230. return;
  1231. }
  1232. if (m_mythread.ThreadState == ThreadState.Stopped)
  1233. {
  1234. m_mythread = new Thread(new ParameterizedThreadStart(ControlThread_GO));
  1235. }
  1236. Point point = CalculateParticleCenterPosition(result,
  1237. new Point(particle.SEMPosX, particle.SEMPosY),
  1238. new Point(particle.PosX, particle.PosY));
  1239. //改为线程调用,先判断线程状态
  1240. m_mythread.Start(point);
  1241. }
  1242. private void ToolStripMenuItem_exportimagefile_Click(object sender, EventArgs e)
  1243. {
  1244. using (FolderBrowserDialog fbd = new FolderBrowserDialog())
  1245. {
  1246. if (fbd.ShowDialog() != DialogResult.OK) return;
  1247. m_imagefilepath = fbd.SelectedPath;
  1248. for (int i = 0; i < dgV_ParticlesDevidePage.Rows.Count; i++)
  1249. {
  1250. if (dgV_ParticlesDevidePage.Rows[i].Cells[2].Value is Bitmap ls_bp)
  1251. {
  1252. string filePath = Path.Combine(m_imagefilepath, $"{(i + 1)}.jpg");
  1253. ls_bp.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
  1254. }
  1255. }
  1256. string str9 = table?["str9"].ToString() ?? "导出完成,共导出 ";
  1257. MessageBox.Show(str9 + dgV_ParticlesDevidePage.Rows.Count.ToString());
  1258. }
  1259. }
  1260. private void testToolStripMenuItem_Click(object sender, EventArgs e)
  1261. {
  1262. // Empty method placeholder
  1263. }
  1264. private void btn_Sel_Click(object sender, EventArgs e)
  1265. {
  1266. condition = "";
  1267. if (!ValidateAndAddCondition(tBx_AreaMin.Text, "Area", ">"))
  1268. return;
  1269. if (!ValidateAndAddCondition(Tbx_AreaMax.Text, "Area", "<"))
  1270. return;
  1271. if (!string.IsNullOrWhiteSpace(tBx_AreaMin.Text) &&
  1272. !string.IsNullOrWhiteSpace(Tbx_AreaMax.Text))
  1273. {
  1274. if (!CompareInput(tBx_AreaMin.Text, Tbx_AreaMax.Text))
  1275. {
  1276. ShowErrorMessage("str11");
  1277. return;
  1278. }
  1279. }
  1280. if (!ValidateAndAddCondition(tbx_DmaxMin.Text, "DMAX", ">"))
  1281. return;
  1282. if (!ValidateAndAddCondition(tbx_DmaxMax.Text, "DMAX", "<"))
  1283. return;
  1284. if (!string.IsNullOrWhiteSpace(tbx_DmaxMin.Text) &&
  1285. !string.IsNullOrWhiteSpace(tbx_DmaxMax.Text))
  1286. {
  1287. if (!CompareInput(tbx_DmaxMin.Text, tbx_DmaxMax.Text))
  1288. {
  1289. ShowErrorMessage("str11");
  1290. return;
  1291. }
  1292. }
  1293. if (!ValidateIntegerField(tB_FieldId.Text, "FieldId"))
  1294. return;
  1295. if (!ValidateIntegerField(tB_ParticleId.Text, "ParticleId"))
  1296. return;
  1297. if (!ValidateAndAddCondition(tbx_DferretMin.Text, "DFERET", ">"))
  1298. return;
  1299. if (!ValidateAndAddCondition(tbx_DferretMax.Text, "DFERET", "<"))
  1300. return;
  1301. if (!string.IsNullOrWhiteSpace(tbx_DferretMin.Text) &&
  1302. !string.IsNullOrWhiteSpace(tbx_DferretMax.Text))
  1303. {
  1304. if (!CompareInput(tbx_DferretMin.Text, tbx_DferretMax.Text))
  1305. {
  1306. ShowErrorMessage("str11");
  1307. return;
  1308. }
  1309. }
  1310. if (!ProcessECDConditions())
  1311. return;
  1312. if (!string.IsNullOrWhiteSpace(tbx_Type.Text))
  1313. {
  1314. string[] types = tbx_Type.Text.Split('$');
  1315. condition += " and (";
  1316. for (int i = 0; i < types.Length; i++)
  1317. {
  1318. if (i == 0)
  1319. {
  1320. condition += $" TypeName = '{types[i]}'";
  1321. }
  1322. else
  1323. {
  1324. condition += $" or TypeName = '{types[i]}'";
  1325. }
  1326. }
  1327. condition += ")";
  1328. }
  1329. if (m_frm_userprogress?.IsDisposed != false)
  1330. {
  1331. ProgressStart();
  1332. }
  1333. UpdateDataGrid();
  1334. lnkFirst_Click(null, null);
  1335. SetDataGridViewStyle();
  1336. }
  1337. /// <summary>
  1338. /// 分页属性改变了。
  1339. /// </summary>
  1340. private void txtPageSize_TextChanged(object sender, EventArgs e)
  1341. {
  1342. if (!int.TryParse(txtPageNum.Text.Trim(), out int num) || num <= 0)
  1343. {
  1344. txtPageNum.Text = "1";
  1345. }
  1346. }
  1347. private void lnkFirst_Click(object sender, EventArgs e)
  1348. {
  1349. PageIndex = 1;
  1350. DrawControl(true);
  1351. }
  1352. private void lnkPrev_Click(object sender, EventArgs e)
  1353. {
  1354. PageIndex = Math.Max(1, PageIndex - 1);
  1355. DrawControl(true);
  1356. }
  1357. private void lnkNext_Click(object sender, EventArgs e)
  1358. {
  1359. PageIndex = Math.Min(PageCount, PageIndex + 1);
  1360. DrawControl(true);
  1361. }
  1362. private void lnkLast_Click(object sender, EventArgs e)
  1363. {
  1364. PageIndex = PageCount;
  1365. DrawControl(true);
  1366. }
  1367. /// <summary>
  1368. /// 跳转
  1369. /// </summary>
  1370. /// <param name="sender"></param>
  1371. /// <param name="e"></param>
  1372. private void btnGo_Click(object sender, EventArgs e)
  1373. {
  1374. if (int.TryParse(txtPageNum.Text.Trim(), out int num) && num > 0)
  1375. {
  1376. if (num > PageCount)
  1377. {
  1378. num = PageCount;
  1379. txtPageNum.Text = PageCount.ToString();
  1380. }
  1381. PageIndex = num;
  1382. DrawControl(true);
  1383. }
  1384. }
  1385. private void cbB_PageSize_SelectedIndexChanged(object sender, EventArgs e)
  1386. {
  1387. DisplayData();
  1388. }
  1389. private void EXCELToolStripMenuItem_Click(object sender, EventArgs e)
  1390. {
  1391. using (var sfd = new OTSIncAReportApp._1_UI.Control_Grids.SpectrumExportConfirmation())
  1392. {
  1393. if (sfd.ShowDialog() != DialogResult.OK) return;
  1394. if (m_frm_userprogress?.IsDisposed != false)
  1395. {
  1396. ProgressStart();
  1397. }
  1398. try
  1399. {
  1400. ExcelExport excelExport=new ExcelExport(dgV_ParticlesDevidePage,particlesFilter,Particledata, m_frm_userprogress);
  1401. excelExport.ExportToExcel(sfd);
  1402. }
  1403. finally
  1404. {
  1405. //加载完成,关闭进度条
  1406. if (m_frm_userprogress != null && !m_frm_userprogress.IsDisposed)
  1407. {
  1408. m_frm_userprogress.SetProgressValueAndText(100, "导出完成");
  1409. m_frm_userprogress.Close();
  1410. }
  1411. Cursor = Cursors.Default;
  1412. //导出完成后,打开Excel文件
  1413. if (File.Exists(sfd.FileName))
  1414. {
  1415. System.Diagnostics.Process.Start(sfd.FileName);
  1416. }
  1417. }
  1418. }
  1419. }
  1420. private void ToolStripMenuItem3_Click(object sender, EventArgs e)
  1421. {
  1422. //如果没有选中颗粒退出
  1423. if (dgV_ParticlesDevidePage.SelectedRows.Count == 0)
  1424. {
  1425. return;
  1426. }
  1427. string categoryName = GetSelectedCategoryName();
  1428. var classificationData = GetClassificationData();
  1429. using (var modifyCategoryForm = new ModifyCategoryForm(classificationData, categoryName))
  1430. {
  1431. if (modifyCategoryForm.ShowDialog() != DialogResult.OK ||
  1432. !modifyCategoryForm.DoYouWantToModifyIt)
  1433. {
  1434. return;
  1435. }
  1436. var updateParams = GetUpdateParameters(modifyCategoryForm);
  1437. HandleCategoryUpdate(updateParams);
  1438. }
  1439. }
  1440. private void ToolStripMenuItem_Delete_Particle_Click(object sender, EventArgs e)
  1441. {
  1442. string path = result.FilePath;
  1443. var fieldData = new ParticleData(result.FilePath);
  1444. List<Particle> particles = fieldData.GetParticleAllList();
  1445. DialogResult dr = MessageBox.Show("Remove all these particles permanently?",
  1446. "Tips", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
  1447. if (dr == DialogResult.OK)
  1448. {
  1449. DeleteSelectedParticles(particles);
  1450. }
  1451. }
  1452. private void btn_particletypesel_Click(object sender, EventArgs e)
  1453. {
  1454. ParticleClassificationSelect particleClassificationSelect = new ParticleClassificationSelect(this, tbx_Type.Text);
  1455. DialogResult result = particleClassificationSelect.ShowDialog();
  1456. if (result == DialogResult.OK)
  1457. {
  1458. condition = "";
  1459. tbx_Type.Text = "";
  1460. if (particleClassificationSelect.ParticleClassificationSelected != "")
  1461. {
  1462. tbx_Type.Text = particleClassificationSelect.ParticleClassificationSelected;
  1463. btn_Sel_Click(null, null);
  1464. }
  1465. }
  1466. }
  1467. private void btn_showconfig_Click(object sender, EventArgs e)
  1468. {
  1469. var p = particlesFilter; List<string> ele = new List<string>();
  1470. string elementsstr = "";
  1471. foreach (DataRow row in particlesFilter.Rows)
  1472. {
  1473. string[] strcbo = row["Element"].ToString().Split(';');
  1474. for (int j = 0; j < strcbo.Length; j++)
  1475. {
  1476. string[] str = strcbo[j].Split('-');
  1477. if (!ele.Contains(str[0]) && str[0] != "")
  1478. {
  1479. if (str[1] != "" && double.Parse(str[1]) != 0) //咨询demo后,元素含量返回值为零时一般去除此元素
  1480. { ele.Add(str[0]); }
  1481. }
  1482. }
  1483. }
  1484. foreach (var el in ele)
  1485. {
  1486. elementsstr += el.ToString() + ',';
  1487. }
  1488. if (elementsstr != "")
  1489. {
  1490. elementsstr = elementsstr.Remove(elementsstr.Length - 1, 1);
  1491. }
  1492. m_particlesGridDevidePageShowConfig = new ParticlesGridDevidePageShowConfig(m_ReportApp.m_RptConfigFile.Systype, elementsstr);
  1493. m_particlesGridDevidePageShowConfig.ShowDialog();
  1494. if (m_particlesGridDevidePageShowConfig.DialogResult == DialogResult.OK)
  1495. {
  1496. dgV_ParticlesDevidePage.Rows.Clear();
  1497. dgV_ParticlesDevidePage.Columns.Clear();
  1498. RefreshGridView();
  1499. SetDataGridViewStyle();
  1500. }
  1501. }
  1502. private void tbx_Type_Click(object sender, EventArgs e)
  1503. {
  1504. ParticleClassificationSelect particleClassificationSelect = new ParticleClassificationSelect(this, tbx_Type.Text);
  1505. DialogResult result = particleClassificationSelect.ShowDialog();
  1506. if (result == DialogResult.OK)
  1507. {
  1508. condition = "";
  1509. tbx_Type.Text = particleClassificationSelect.ParticleClassificationSelected;
  1510. string[] tr = tbx_Type.Text.Split(',');
  1511. condition += " and (";
  1512. for (int i = 0; i < tr.Length; i++)
  1513. {
  1514. if (i == 0)
  1515. {
  1516. condition += " TypeName = '" + tr[i] + "'";
  1517. }
  1518. else
  1519. {
  1520. condition += " or TypeName = '" + tr[i] + "'";
  1521. }
  1522. }
  1523. condition += ")";
  1524. if (m_frm_userprogress.IsDisposed)
  1525. {
  1526. ProgressStart();
  1527. }
  1528. UpdateDataGrid();
  1529. lnkFirst_Click(null, null);
  1530. SetDataGridViewStyle();
  1531. }
  1532. }
  1533. private void 根据相似度批量修改ToolStripMenuItem_Click(object sender, EventArgs e)
  1534. {
  1535. //如果没有选中颗粒退出
  1536. if (dgV_ParticlesDevidePage.SelectedRows.Count != 1)
  1537. {
  1538. MessageBox.Show("Please select one row!");
  1539. return;
  1540. }
  1541. var SelectRows = dgV_ParticlesDevidePage.SelectedRows;
  1542. DataGridViewRow dgvr = SelectRows[0];
  1543. Bitmap ls_bp = (Bitmap)dgvr.Cells[2].Value;
  1544. List<string> list_str = (List<string>)ls_bp.Tag;
  1545. uint[] Analysis_xray = new uint[2000];
  1546. int i_xray_id = 0;
  1547. List<Element> list_celementchemistryclr = new List<Element>();
  1548. string str = " particleId= " + dgvr.Cells["particleId"].Value.ToString() + " and fieldid = " + dgvr.Cells["fieldid"].Value.ToString();
  1549. DataRow[] drs = particlesFilter.Select(str);
  1550. DataRow row = drs[0];
  1551. string subParticleString = row["SubParticles"].ToString();
  1552. if (subParticleString != "" && subParticleString != null)
  1553. {
  1554. Particledata.GetXrayByParticleTagIDAndFieldID_ForMergeParticle(Convert.ToInt32(dgvr.Cells["particleId"].Value), Convert.ToInt32(dgvr.Cells["fieldid"].Value), out Analysis_xray);
  1555. }
  1556. else
  1557. {
  1558. ReportFun.GetXrayByParticleTagIDAndFieldID_ForDrawDistrbutionImageAndBSE(Convert.ToInt32(dgvr.Cells["particleId"].Value), Convert.ToInt32(dgvr.Cells["fieldid"].Value), out Analysis_xray, out i_xray_id, out list_celementchemistryclr);
  1559. }
  1560. ListOfSimilarParticles Form_listOfSimilarParticles = new ListOfSimilarParticles(this, Analysis_xray, m_ReportApp);
  1561. DialogResult result3 = Form_listOfSimilarParticles.ShowDialog();
  1562. if (result3 == DialogResult.OK)
  1563. {
  1564. UpdateDataGrid();
  1565. lnkFirst_Click(null, null);
  1566. SetDataGridViewStyle();
  1567. DataTable table = GetClassificationOfAllParticles();
  1568. if (table != null)
  1569. {
  1570. if (table.Rows.Count > 0)
  1571. {
  1572. foreach (DataRow rw in table.Rows)
  1573. {
  1574. tbx_Type.Text += rw["TypeName"].ToString() + '$';
  1575. }
  1576. }
  1577. if (tbx_Type.Text != "")
  1578. {
  1579. tbx_Type.Text = tbx_Type.Text.Remove(tbx_Type.Text.Length - 1);
  1580. }
  1581. }
  1582. dgV_ParticlesDevidePage.Focus();
  1583. }
  1584. else
  1585. {
  1586. }
  1587. }
  1588. private void dgV_ParticlesDevidePage_KeyDown(object sender, KeyEventArgs e)
  1589. {
  1590. if (e.KeyData == Keys.Delete)
  1591. {
  1592. ToolStripMenuItem_Delete_Particle_Click(null, null);
  1593. }
  1594. }
  1595. private void dgV_ParticlesDevidePage_KeyUp(object sender, KeyEventArgs e)
  1596. {
  1597. if (e.KeyData == Keys.Down)
  1598. {
  1599. dgV_ParticlesDevidePage_MouseUp(null, null);
  1600. }
  1601. if (e.KeyData == Keys.Up)
  1602. {
  1603. dgV_ParticlesDevidePage_MouseUp(null, null);
  1604. }
  1605. }
  1606. private void dgV_ParticlesDevidePage_MouseUp(object sender, MouseEventArgs e)
  1607. {
  1608. ToolStripMenuItem_SimilarityReclassification.Enabled = false;
  1609. var SelectRows = dgV_ParticlesDevidePage.SelectedRows;
  1610. if (SelectRows.Count != 0)
  1611. {
  1612. if (SelectRows.Count == 1)
  1613. {
  1614. DataGridViewRow dgvr = SelectRows[0];
  1615. uint[] Analysis_xray = new uint[2000];
  1616. Particle particle = new Particle();
  1617. string str = " particleId= " + dgvr.Cells["particleId"].Value.ToString() + " and fieldid = " + dgvr.Cells["fieldid"].Value.ToString();
  1618. DataRow[] drs = particlesFilter.Select(str);
  1619. DataRow row = drs[0];
  1620. string subParticleString = row["SubParticles"].ToString();
  1621. particle = Particledata.GetXrayByParticleIDAndFieldID(subParticleString, Convert.ToInt32(dgvr.Cells["particleId"].Value), Convert.ToInt32(dgvr.Cells["fieldid"].Value), out Analysis_xray);
  1622. List<ShowElementInfo> list_showelementinfo = Particledata.GetShowElementInfos(particle.ElementList);
  1623. string str_IncAName = "";
  1624. str_IncAName = Convert.ToString(dgvr.Cells[1].Value);
  1625. if (particle == null)
  1626. {
  1627. return;
  1628. }
  1629. control_XRayTable1.SetParticleInfo("Area:" + Math.Round(particle.Area, 2) + " " + "DMAX:" + Math.Round(particle.DMAX, 2) + " " + "DELONG:" + Math.Round(particle.DELONG, 2) + " " + "DFERET:" + Math.Round(particle.DFERET, 2) + " " + "DINSCR:" + Math.Round(particle.DINSCR, 2) + "\n" + "DMEAN:" + Math.Round(particle.DMEAN, 2) + " " + "DMIN:" + Math.Round(particle.DMIN, 2) + " " + "DPERP:" + Math.Round(particle.DPERP, 2) + " " + "ORIENTATION:" + Math.Round(particle.ORIENTATION, 2) + " " + "PERIMETER:" + Math.Round(particle.PERIMETER, 2));
  1630. control_XRayTable1.Visible = true;
  1631. control_XRayTable1.SetXRayShowLineValue(Analysis_xray, list_showelementinfo);
  1632. control_XRayTable1.GBInfoStr = "";
  1633. control_XRayTable1.MaterialName = str_IncAName;
  1634. control_XRayTable1.List_ShowElementInfo = list_showelementinfo;
  1635. DataTable dataTable = new DataTable();
  1636. double pix = result.GetPixelSize();
  1637. int width = result.GetImageWidth();
  1638. int height = result.GetImageHeight();
  1639. Dictionary<string, List<Segment>> segsData = new Dictionary<string, List<Segment>>();
  1640. if (subParticleString == "" || subParticleString == null)
  1641. {
  1642. int fldid = Convert.ToInt32(dgvr.Cells["fieldid"].Value);
  1643. int partid = Convert.ToInt32(dgvr.Cells["particleId"].Value);
  1644. var listseg = Particledata.GetSegmentData(fldid, partid);
  1645. string key = fldid.ToString() + "_" + partid.ToString();
  1646. segsData.Add(key, listseg);
  1647. dataTable = particlesFilter.Clone();
  1648. dataTable.ImportRow(row);
  1649. }
  1650. else
  1651. {
  1652. string vs = "," + subParticleString.Replace(':', '-') + ",";
  1653. dataTable = Particledata.GetParticleAllForBig(vs);//组成拼接颗粒的子颗粒
  1654. foreach (DataRow dow in dataTable.Rows)
  1655. {
  1656. int fldid = Convert.ToInt32(dow["fieldid"]);
  1657. int partid = Convert.ToInt32(dow["particleId"]);
  1658. var listseg = Particledata.GetSegmentData(fldid, partid);
  1659. string key = dow["fieldid"].ToString() + "_" + dow["particleid"].ToString();
  1660. segsData.Add(key, listseg);
  1661. }
  1662. }
  1663. Bitmap bmap = fldImgAccess.GetBitmapForParticleAll(subParticleString, dataTable, pix, height, width);
  1664. Bitmap bmap1 = fldImgAccess.GetBitmapForParticleAllWithBlackAndWhite(subParticleString, dataTable, segsData, pix, height, width);
  1665. control_XRayTable1.SetBitmapOfPictureBox(bmap, bmap1);
  1666. Invalidate();
  1667. ToolStripMenuItem_SimilarityReclassification.Enabled = true;
  1668. }
  1669. SaveParticleslist_select();
  1670. }
  1671. }
  1672. private void dgV_ParticlesDevidePage_MouseDown(object sender, MouseEventArgs e)
  1673. {
  1674. ToolStripMenuItemDelete_Particle.Visible = true;
  1675. }
  1676. #endregion
  1677. #endregion
  1678. #region 连接电镜相关
  1679. /// <summary>
  1680. /// 移动SEM到指定位置线程函数
  1681. /// </summary>
  1682. private void ControlThread_GO(object in_obj)
  1683. {
  1684. if (m_mythread_state) return;
  1685. m_mythread_state = true;
  1686. try
  1687. {
  1688. Point sem_point = (Point)in_obj;
  1689. //第一步,连接电镜
  1690. m_OTSIncAReportGridsFun?.Connection_ForParticlesGrid();
  1691. Thread.Sleep(500);
  1692. //第二步,移动到指定位置,先读取再设置
  1693. if (m_OTSIncAReportGridsFun?.m_SEMConnectionState == true)
  1694. {
  1695. m_OTSIncAReportGridsFun.MoveSemToPointXY_ForParticlesGrid(sem_point.X, sem_point.Y);
  1696. }
  1697. Thread.Sleep(1500);
  1698. }
  1699. finally
  1700. {
  1701. m_mythread_state = false;
  1702. }
  1703. }
  1704. #endregion
  1705. #region 类别修改相关
  1706. /// <summary>
  1707. /// 读取标准库的ClassifySTD表
  1708. /// </summary>
  1709. /// <param name="a_address"></param>
  1710. /// <returns></returns>
  1711. private DataTable ReadClassification(string a_address, string STDName)
  1712. {
  1713. DataTable dt_STDGroups = new DataTable();
  1714. DataTable dt_ClassifySTD = new DataTable();
  1715. DataTable dt_IncAData = new DataTable();
  1716. var systype = m_ReportApp.m_RptConfigFile.Systype;
  1717. if (systype == OTS_SysType_ID.IncA)
  1718. {
  1719. dt_ClassifySTD.Columns.Add("STDId");
  1720. dt_ClassifySTD.Columns.Add("StrName");
  1721. dt_ClassifySTD.Columns.Add("Color");
  1722. dt_ClassifySTD.Columns.Add("KeyElementList");
  1723. dt_ClassifySTD.Columns.Add("SubElementList");
  1724. dt_ClassifySTD.Columns.Add("UsingImgPropertyList");
  1725. dt_ClassifySTD.Columns.Add("UsingOtherPropertyList");
  1726. dt_ClassifySTD.Columns.Add("Expression");
  1727. dt_ClassifySTD.Columns.Add("Hardness");
  1728. dt_ClassifySTD.Columns.Add("Density");
  1729. dt_ClassifySTD.Columns.Add("Electrical_conductivity");
  1730. dt_ClassifySTD.Columns.Add("BSE");
  1731. dt_ClassifySTD.Columns.Add("Formula");
  1732. dt_ClassifySTD.Columns.Add("Element");
  1733. dt_ClassifySTD.Columns.Add("IfElementAnalysis");
  1734. dt_ClassifySTD.Columns.Add("ListNum");
  1735. dt_ClassifySTD.Columns.Add("GroupId");
  1736. dt_ClassifySTD.Columns.Add("GroupName");
  1737. dt_ClassifySTD.Columns.Add("GroupColor");
  1738. DataTable da = Particledata.GetParticleListForParticlSizeID("area", "");
  1739. for (int i = 0; i < da.Rows.Count; i++)
  1740. {
  1741. if (Convert.ToInt64(da.Rows[i]["TypeId"]) > 9)
  1742. {
  1743. DataRow newRow = dt_ClassifySTD.NewRow();
  1744. newRow["STDId"] = da.Rows[i]["TypeId"];
  1745. newRow["StrName"] = da.Rows[i]["TypeName"];
  1746. newRow["Color"] = da.Rows[i]["TypeColor"];
  1747. newRow["GroupId"] = da.Rows[i]["GroupId"];
  1748. newRow["GroupName"] = da.Rows[i]["GroupName"];
  1749. newRow["GroupColor"] = da.Rows[i]["GroupColor"];
  1750. dt_ClassifySTD.Rows.Add(newRow);
  1751. }
  1752. }
  1753. }
  1754. else
  1755. {
  1756. SqLiteHelper sh_STDGroups = new SqLiteHelper("data source='" + a_address + "\\" + STDName + ".db" + "'");
  1757. dt_STDGroups = sh_STDGroups.ExecuteQuery("select * from STDGroups");
  1758. SqLiteHelper sh_ClassifySTD = new SqLiteHelper("data source='" + a_address + "\\" + STDName + ".db" + "'");
  1759. dt_ClassifySTD = sh_ClassifySTD.ExecuteQuery("select * from ClassifySTD");
  1760. dt_ClassifySTD.Columns.Add("GroupName");
  1761. dt_ClassifySTD.Columns.Add("GroupColor");
  1762. for (int i = 0; i < dt_ClassifySTD.Rows.Count; i++)
  1763. {
  1764. for (int a = 0; a < dt_STDGroups.Rows.Count; a++)
  1765. {
  1766. if (dt_ClassifySTD.Rows[i]["GroupId"].ToString() == dt_STDGroups.Rows[a]["id"].ToString())
  1767. {
  1768. dt_ClassifySTD.Rows[i]["GroupName"] = dt_STDGroups.Rows[a]["name"].ToString();
  1769. dt_ClassifySTD.Rows[i]["GroupColor"] = dt_STDGroups.Rows[a]["color"].ToString();
  1770. continue;
  1771. }
  1772. }
  1773. }
  1774. SqLiteHelper sh_Inclusion = new SqLiteHelper("data source='" + a_address + "\\FIELD_FILES\\Inclusion.db" + "'");
  1775. dt_IncAData = sh_Inclusion.ExecuteQuery("select * from IncAData");
  1776. for (int i = 0; i < dt_IncAData.Rows.Count; i++)
  1777. {
  1778. if (Convert.ToInt64(dt_IncAData.Rows[i]["TypeId"]) > 50000)
  1779. {
  1780. DataRow newRow = dt_ClassifySTD.NewRow();
  1781. newRow["STDId"] = dt_IncAData.Rows[i]["TypeId"];
  1782. newRow["StrName"] = dt_IncAData.Rows[i]["TypeName"];
  1783. newRow["Color"] = dt_IncAData.Rows[i]["TypeColor"];
  1784. newRow["GroupId"] = dt_IncAData.Rows[i]["GroupId"];
  1785. newRow["GroupName"] = dt_IncAData.Rows[i]["GroupName"];
  1786. newRow["GroupColor"] = dt_IncAData.Rows[i]["GroupColor"];
  1787. dt_ClassifySTD.Rows.Add(newRow);
  1788. }
  1789. }
  1790. }
  1791. DataRow newRowInvalid = dt_ClassifySTD.NewRow();
  1792. newRowInvalid["STDId"] = -1;
  1793. newRowInvalid["StrName"] = "Invalid";
  1794. newRowInvalid["Color"] = "#000000";
  1795. newRowInvalid["GroupId"] = -1;
  1796. newRowInvalid["GroupName"] = "Invalid";
  1797. newRowInvalid["GroupColor"] = "#000000";
  1798. dt_ClassifySTD.Rows.Add(newRowInvalid);
  1799. return dt_ClassifySTD;
  1800. }
  1801. private string GetSelectedCategoryName()
  1802. {
  1803. if (dgV_ParticlesDevidePage.SelectedRows.Count > 0)
  1804. {
  1805. DataGridViewRow lastRow = dgV_ParticlesDevidePage.SelectedRows[
  1806. dgV_ParticlesDevidePage.SelectedRows.Count - 1];
  1807. return lastRow.Cells[1].Value?.ToString() ?? "";
  1808. }
  1809. return "";
  1810. }
  1811. private DataTable GetClassificationData()
  1812. {
  1813. string[] resultParts = result.GetSTDName().Split('.');
  1814. return ReadClassification(result.FilePath, resultParts[0]);
  1815. }
  1816. private List<string> GetUpdateParameters(ModifyCategoryForm form)
  1817. {
  1818. return new List<string>
  1819. {
  1820. form.OutTypeAndName[0], // TypeId
  1821. form.OutTypeAndName[1], // TypeName
  1822. form.OutTypeAndName[2], // TypeColor
  1823. form.OutTypeAndName[3], // GroupName
  1824. form.OutTypeAndName[4], // GroupID
  1825. form.OutTypeAndName[5] // GroupColor
  1826. };
  1827. }
  1828. private void HandleCategoryUpdate(List<string> updateParams)
  1829. {
  1830. if (dgV_ParticlesDevidePage.SelectedRows.Count == 1)
  1831. {
  1832. HandleSingleRowUpdate(updateParams);
  1833. }
  1834. else
  1835. {
  1836. HandleMultipleRowsUpdate(updateParams);
  1837. }
  1838. RefreshAfterUpdate();
  1839. }
  1840. private void HandleSingleRowUpdate(List<string> updateParams)
  1841. {
  1842. DialogResult result = MessageBox.Show("是否寻找相似颗粒并重命名?", "Tip",
  1843. MessageBoxButtons.YesNo);
  1844. if (result == DialogResult.Yes)
  1845. {
  1846. HandleSimilarParticleSearch(updateParams);
  1847. }
  1848. else
  1849. {
  1850. ExecuteBatchUpdate(updateParams);
  1851. }
  1852. }
  1853. private void HandleSimilarParticleSearch(List<string> updateParams)
  1854. {
  1855. int sel = m_ReportApp.m_conditionChoose.m_conditionData
  1856. .GetComboDownListIndexByItemName(
  1857. OTSIncAReportApp.OTSSampleReportInfo.OTS_REPORT_PROP_GRID_ITEMS.PARTICE_LIST);
  1858. if (sel == (int)SelItem.MergeParticles)
  1859. {
  1860. ExecuteBatchUpdate(updateParams);
  1861. return;
  1862. }
  1863. uint[] analysisXray = new uint[2000];
  1864. if (dgV_ParticlesDevidePage.SelectedRows.Count == 1)
  1865. {
  1866. DataGridViewRow row = dgV_ParticlesDevidePage.SelectedRows[0];
  1867. ReportFun.GetXrayByParticleTagIDAndFieldID_ForDrawDistrbutionImageAndBSE(
  1868. Convert.ToInt32(row.Cells["particleId"].Value),
  1869. Convert.ToInt32(row.Cells["fieldid"].Value),
  1870. out analysisXray,
  1871. out int _, // i_xray_id
  1872. out List<Element> _); // list_celementchemistryclr
  1873. }
  1874. using (var form = new ListOfSimilarParticles(this, analysisXray, updateParams, m_ReportApp))
  1875. {
  1876. if (form.ShowDialog() != DialogResult.OK)
  1877. {
  1878. ExecuteBatchUpdate(updateParams);
  1879. }
  1880. }
  1881. }
  1882. private void HandleMultipleRowsUpdate(List<string> updateParams)
  1883. {
  1884. ExecuteBatchUpdate(updateParams);
  1885. }
  1886. private void ExecuteBatchUpdate(List<string> updateParams)
  1887. {
  1888. var cmdList = new List<KeyValuePair<string, SQLiteParameter[]>>();
  1889. foreach (DataGridViewRow row in dgV_ParticlesDevidePage.SelectedRows)
  1890. {
  1891. UpdateGridRow(row, updateParams[1]); // TypeName
  1892. if (row.Cells[2].Value is Bitmap bitmap && bitmap.Tag is List<string> tagList)
  1893. {
  1894. var particleIds = new List<int>
  1895. {
  1896. Convert.ToInt32(tagList[0]), // fieldId
  1897. Convert.ToInt32(tagList[1]) // particleId
  1898. };
  1899. var cmd = Particledata.GetUpdataAIncACmd(particleIds, updateParams);
  1900. cmdList.Add(cmd);
  1901. }
  1902. row.Cells[1].Value = updateParams[1]; // Update TypeName in grid
  1903. }
  1904. Particledata.ExecuteNonQueryBatch(cmdList);
  1905. }
  1906. private void UpdateGridRow(DataGridViewRow row, string typeName)
  1907. {
  1908. row.Cells[1].Value = typeName;
  1909. }
  1910. private void RefreshAfterUpdate()
  1911. {
  1912. UpdateDataGrid();
  1913. lnkFirst_Click(null, null);
  1914. SetDataGridViewStyle();
  1915. UpdateTypeTextBox();
  1916. dgV_ParticlesDevidePage.Focus();
  1917. }
  1918. private void UpdateTypeTextBox()
  1919. {
  1920. tbx_Type.Text = "";
  1921. DataTable table = GetClassificationOfAllParticles();
  1922. if (table?.Rows.Count > 0)
  1923. {
  1924. tbx_Type.Text = string.Join("$", table.AsEnumerable()
  1925. .Select(row => row["TypeName"].ToString()));
  1926. }
  1927. }
  1928. #endregion
  1929. #region 删除颗粒相关\备份
  1930. private void DeleteSelectedParticles(List<Particle> particles)
  1931. {
  1932. var deletedParticles = new List<Particle>();
  1933. foreach (DataGridViewRow row in dgV_ParticlesDevidePage.SelectedRows)
  1934. {
  1935. if (row.Cells[2].Value is Bitmap bitmap && bitmap.Tag is List<string> tagList)
  1936. {
  1937. int fieldId = Convert.ToInt32(tagList[0]);
  1938. int particleId = Convert.ToInt32(tagList[1]);
  1939. Particle particleToDelete = particles.FirstOrDefault(p =>
  1940. p.FieldId == fieldId && p.ParticleId == particleId);
  1941. if (particleToDelete != null &&
  1942. DeleteParticlesFromSTDDb(particleToDelete.ParticleId, particleToDelete.FieldId))
  1943. {
  1944. RemoveParticleFromDataTable(particleToDelete);
  1945. deletedParticles.Add(particleToDelete);
  1946. }
  1947. else
  1948. {
  1949. MessageBox.Show("Delete failed");
  1950. break;
  1951. }
  1952. }
  1953. }
  1954. UpdateUIAfterDeletion(deletedParticles.Count);
  1955. //SynchronizeParticleDeletion(deletedParticles);
  1956. }
  1957. private void RemoveParticleFromDataTable(Particle particle)
  1958. {
  1959. for (int i = particlesAll.Rows.Count - 1; i >= 0; i--)
  1960. {
  1961. if (particlesAll.Rows[i]["Fieldid"].ToString() == particle.FieldId.ToString() &&
  1962. particlesAll.Rows[i]["Particleid"].ToString() == particle.ParticleId.ToString())
  1963. {
  1964. particlesAll.Rows.RemoveAt(i);
  1965. break;
  1966. }
  1967. }
  1968. }
  1969. private void UpdateUIAfterDeletion(int deletedCount)
  1970. {
  1971. RecordCount = recordCount - deletedCount;
  1972. lblTotalCount.Text = RecordCount.ToString();
  1973. // Remove rows from grid (in reverse order to avoid index issues)
  1974. var rowsToRemove = dgV_ParticlesDevidePage.SelectedRows.Cast<DataGridViewRow>().ToList();
  1975. foreach (var row in rowsToRemove)
  1976. {
  1977. dgV_ParticlesDevidePage.Rows.Remove(row);
  1978. }
  1979. if (dgV_ParticlesDevidePage.Rows.Count == 0)
  1980. {
  1981. DisplayData();
  1982. }
  1983. else
  1984. {
  1985. // Update row numbers
  1986. for (int j = 0; j < dgV_ParticlesDevidePage.Rows.Count; j++)
  1987. {
  1988. dgV_ParticlesDevidePage.Rows[j].Cells[0].Value =
  1989. (pageSize * (PageIndex - 1) + j + 1).ToString();
  1990. }
  1991. }
  1992. }
  1993. private void SynchronizeParticleDeletion(List<Particle> deletedParticles)
  1994. {
  1995. if (m_ReportApp.im_Control_DrawDistrbutionImageAndBSE != null)
  1996. {
  1997. m_ReportApp.im_Control_DrawDistrbutionImageAndBSE.DeletesParticlesSynchronously(deletedParticles);
  1998. }
  1999. else
  2000. {
  2001. using (var control = new OTSIncAReportGraph.Controls.Control_DrawDistrbutionImageAndBSE(m_ReportApp))
  2002. {
  2003. foreach (var particle in deletedParticles)
  2004. {
  2005. control.DeleteParticlesFromSTDDb(particle.ParticleId, particle.FieldId);
  2006. }
  2007. }
  2008. }
  2009. }
  2010. private bool DeleteParticlesFromSTDDb(int particleId, int fieldId)
  2011. {
  2012. if (!CheckAndCreateBackup())
  2013. return false;
  2014. //防止为空校验判断
  2015. if (result.GetList_OTSField() == null)
  2016. return false;
  2017. try
  2018. {
  2019. //Particle particle = result.GetList_OTSField()
  2020. // .Find(x => x.FieldID == fieldId)?
  2021. // .ParticleList.Find(x => x.ParticleId == particleId);
  2022. //if (particle == null)
  2023. // return false;
  2024. var particleData = new ParticleData(result.FilePath);
  2025. return particleData.DeleteFromData(
  2026. Convert.ToString(fieldId),
  2027. Convert.ToString(particleId));
  2028. }
  2029. catch (Exception ex)
  2030. {
  2031. log.Error($"Error deleting particle: {ex.Message}");
  2032. return false;
  2033. }
  2034. }
  2035. private bool CheckAndCreateBackup()
  2036. {
  2037. bool backupExists = Enumerable.Range(1, 200).Any(i =>
  2038. Directory.Exists(Path.Combine(result.FilePath, "FIELD_FILES", "Backups" + i)));
  2039. if (!backupExists)
  2040. {
  2041. return BackupDatabase();
  2042. }
  2043. return true;
  2044. }
  2045. private bool BackupDatabase()
  2046. {
  2047. try
  2048. {
  2049. //创建备份数据库文件夹
  2050. string sourcePath = Path.Combine(result.FilePath, "FIELD_FILES", "Inclusion.db");
  2051. string sourceName = "Inclusion.db";
  2052. string folderPath = Path.Combine(result.FilePath, "FIELD_FILES", "Backups");
  2053. string backupFolder = "";
  2054. for (int i = 1; i <= 200; i++)
  2055. {
  2056. string currentPath = Path.Combine(folderPath, i.ToString());
  2057. if (!Directory.Exists(currentPath))
  2058. {
  2059. Directory.CreateDirectory(currentPath);
  2060. backupFolder = currentPath;
  2061. break;
  2062. }
  2063. }
  2064. if (string.IsNullOrEmpty(backupFolder))
  2065. {
  2066. return false;
  2067. }
  2068. //复制数据库文件
  2069. string targetPath = Path.Combine(backupFolder, sourceName);
  2070. File.Copy(sourcePath, targetPath, true);
  2071. return true;
  2072. }
  2073. catch (Exception ex)
  2074. {
  2075. log.Error($"Error backing up database: {ex.Message}");
  2076. return false;
  2077. }
  2078. }
  2079. #endregion
  2080. #region 报表输出
  2081. /// <summary>
  2082. ///
  2083. /// </summary>
  2084. /// <param name="str_resultPath"></param>
  2085. /// <param name="dataTable"></param>
  2086. /// <param name="vs"></param>
  2087. /// <param name="dt_FIeld"></param>
  2088. public void Out_MarkParticleRectangleOnFieldFile(string str_resultPath, DataTable dataTable,
  2089. out List<string> vs, out DataTable dt_FIeld)
  2090. {
  2091. Init();
  2092. var fieldIds = ExtractFieldIds(dataTable);
  2093. string str_path_FIELD_FILES = Path.Combine(str_resultPath, "FIELD_FILES");
  2094. dt_FIeld = new DataTable();
  2095. vs = new List<string>();
  2096. ResultFile resfile = m_ReportApp.m_rstDataMgr.ResultFilesList[
  2097. m_ReportApp.m_rstDataMgr.GetWorkingResultId()];
  2098. float pixelSize = resfile.GetPixelSize();
  2099. float scanFieldSizeX = resfile.GetScanFieldSizeX();
  2100. int gauge = RulerSelection(scanFieldSizeX);
  2101. float rulerPixels = gauge / pixelSize;
  2102. var fieldData = new FieldData(resfile.FilePath);
  2103. DataTable dt_AllParticle = fieldData.GetAllParticle_DataTable();
  2104. var directoryInfo = new DirectoryInfo(str_path_FIELD_FILES);
  2105. if (directoryInfo.Exists)
  2106. {
  2107. ProcessFieldFiles(directoryInfo, fieldIds, dataTable, dt_AllParticle,
  2108. rulerPixels, gauge, ref dt_FIeld, vs);
  2109. }
  2110. }
  2111. private List<string> ExtractFieldIds(DataTable dataTable)
  2112. {
  2113. return dataTable.AsEnumerable()
  2114. .Where(row => Convert.ToInt32(row["TypeId"]) > 9)
  2115. .Take(10)
  2116. .Select(row => row["Fieldid"].ToString())
  2117. .Distinct()
  2118. .ToList();
  2119. }
  2120. private void ProcessFieldFiles(DirectoryInfo directoryInfo, List<string> fieldIds,
  2121. DataTable dataTable, DataTable allParticles, float rulerPixels, int gauge,
  2122. ref DataTable dt_FIeld, List<string> vs)
  2123. {
  2124. var fieldFiles = directoryInfo.GetFiles("Field*.bmp")
  2125. .ToDictionary(f => GetFieldIdFromFile(f.Name), f => f,
  2126. StringComparer.OrdinalIgnoreCase);
  2127. var resultTable = CreateFieldDataTable();
  2128. foreach (string fieldId in fieldIds.Where(id => fieldFiles.ContainsKey(id)))
  2129. {
  2130. var file = fieldFiles[fieldId];
  2131. int count = dataTable.AsEnumerable()
  2132. .Count(row => row["fieldid"].ToString() == fieldId);
  2133. DataRow dr = resultTable.NewRow();
  2134. dr["fieldid"] = $" fieldid = {fieldId}";
  2135. dr["cunt"] = count;
  2136. dr["fieldName"] = file.Name;
  2137. dr["fieldFullName"] = file.FullName;
  2138. dr["id"] = fieldId;
  2139. resultTable.Rows.Add(dr);
  2140. }
  2141. dt_FIeld = resultTable.Copy();
  2142. dt_FIeld.Columns.Add("Field_pic", typeof(Bitmap));
  2143. ProcessFieldImages(allParticles, rulerPixels, gauge, dt_FIeld, vs);
  2144. }
  2145. private string GetFieldIdFromFile(string fileName)
  2146. {
  2147. string nameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
  2148. return nameWithoutExtension.Length > 5 ?
  2149. nameWithoutExtension.Substring(5) : nameWithoutExtension;
  2150. }
  2151. private DataTable CreateFieldDataTable()
  2152. {
  2153. var dt = new DataTable();
  2154. dt.Columns.Add("fieldid");
  2155. dt.Columns.Add("id");
  2156. dt.Columns.Add("fieldName");
  2157. dt.Columns.Add("cunt", typeof(int));
  2158. dt.Columns.Add("fieldFullName");
  2159. return dt;
  2160. }
  2161. private void ProcessFieldImages(DataTable allParticles, float rulerPixels, int gauge,
  2162. DataTable dt_FIeld, List<string> vs)
  2163. {
  2164. var particleGroups = allParticles.AsEnumerable()
  2165. .GroupBy(row => row["fieldid"].ToString())
  2166. .ToDictionary(g => g.Key, g => g.ToList());
  2167. foreach (DataRow row in dt_FIeld.Rows.Cast<DataRow>().ToList())
  2168. {
  2169. string fieldId = row["id"].ToString();
  2170. if (!particleGroups.ContainsKey(fieldId) ||
  2171. particleGroups[fieldId].Count == 0)
  2172. continue;
  2173. vs.Add(fieldId);
  2174. try
  2175. {
  2176. using (var img = Image.FromFile(row["fieldFullName"].ToString()))
  2177. {
  2178. using (var fieldBitmap = new Bitmap(img.Width, img.Height,
  2179. System.Drawing.Imaging.PixelFormat.Format32bppArgb))
  2180. {
  2181. DrawBaseImage(img, fieldBitmap);
  2182. MarkParticlesOnImage(particleGroups[fieldId], fieldBitmap,
  2183. row, fieldId, rulerPixels, gauge);
  2184. }
  2185. }
  2186. }
  2187. catch (Exception ex)
  2188. {
  2189. log.Error($"Error processing field image: {ex.Message}");
  2190. }
  2191. }
  2192. }
  2193. private void DrawBaseImage(Image sourceImage, Bitmap targetBitmap)
  2194. {
  2195. using (Graphics g = Graphics.FromImage(targetBitmap))
  2196. {
  2197. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  2198. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  2199. g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
  2200. g.DrawImage(sourceImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height));
  2201. }
  2202. }
  2203. private void MarkParticlesOnImage(List<DataRow> particles, Bitmap fieldBitmap,
  2204. DataRow fieldRow, string fieldId, float rulerPixels, int gauge)
  2205. {
  2206. foreach (DataRow particleRow in particles)
  2207. {
  2208. string particleId = particleRow["particleid"].ToString();
  2209. var rectangle = new Rectangle(
  2210. Convert.ToInt32(particleRow["RectLeft"]),
  2211. Convert.ToInt32(particleRow["RectTop"]),
  2212. Convert.ToInt32(particleRow["RectWidth"]),
  2213. Convert.ToInt32(particleRow["RectHeight"])
  2214. );
  2215. MarkParticleOnImage(fieldBitmap, rectangle, fieldId, particleId);
  2216. }
  2217. using (var rulerBitmap = DrawRuler(fieldBitmap, (int)(rulerPixels / 2), 2,
  2218. $"{gauge / 2}μm"))
  2219. {
  2220. fieldRow["Field_pic"] = new Bitmap(rulerBitmap);
  2221. }
  2222. }
  2223. private void MarkParticleOnImage(Bitmap fieldBitmap, Rectangle rectangle,
  2224. string fieldId, string particleId)
  2225. {
  2226. using (Graphics g = Graphics.FromImage(fieldBitmap))
  2227. using (var pen = new Pen(Color.Aquamarine))
  2228. {
  2229. g.DrawRectangle(pen, rectangle);
  2230. int textX = rectangle.X + rectangle.Width > fieldBitmap.Width - 10 ?
  2231. rectangle.X - 10 : rectangle.X + rectangle.Width;
  2232. using (var font = new Font("黑体", 8))
  2233. using (var brush = new SolidBrush(Color.Aqua))
  2234. {
  2235. g.DrawString($"{fieldId} {particleId}", font, brush,
  2236. new PointF(textX, rectangle.Y));
  2237. }
  2238. }
  2239. }
  2240. /// <summary>
  2241. /// 在图片上绘制标尺
  2242. /// </summary>
  2243. /// <param name="bitmap">图片</param>
  2244. /// <param name="lineLength">线长(像素)</param>
  2245. /// <param name="lineWidth">线宽(像素)</param>
  2246. /// <param name="text">显示文本</param>
  2247. /// <returns></returns>
  2248. private Bitmap DrawRuler(Bitmap bitmap, int lineLength, int lineWidth, string text)
  2249. {
  2250. if (bitmap == null)
  2251. throw new ArgumentNullException(nameof(bitmap));
  2252. var rgbBitmap = new Bitmap(bitmap.Width, bitmap.Height);
  2253. using (Graphics graphics = Graphics.FromImage(rgbBitmap))
  2254. {
  2255. graphics.DrawImage(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
  2256. Color color = Color.LimeGreen;
  2257. using (var pen = new Pen(color, lineWidth))
  2258. using (var font = new Font("Arial", 20, GraphicsUnit.Pixel))
  2259. using (var brush = new SolidBrush(color))
  2260. {
  2261. var stringFormat = new StringFormat
  2262. {
  2263. Alignment = StringAlignment.Center,
  2264. LineAlignment = StringAlignment.Center
  2265. };
  2266. int startX = 20;
  2267. int startY = bitmap.Height - 30;
  2268. graphics.DrawLine(pen, startX, startY, startX + lineLength, startY);
  2269. graphics.DrawString(text, font, brush,
  2270. new PointF(startX + lineLength / 2, startY - 20), stringFormat);
  2271. }
  2272. }
  2273. return rgbBitmap;
  2274. }
  2275. private int RulerSelection(float scanFieldSizeX)
  2276. {
  2277. // 根据扫描场尺寸选择合适的标尺单位
  2278. if (scanFieldSizeX >= 1000) return 1000;
  2279. if (scanFieldSizeX >= 500) return 500;
  2280. if (scanFieldSizeX >= 200) return 200;
  2281. if (scanFieldSizeX >= 100) return 100;
  2282. if (scanFieldSizeX >= 50) return 50;
  2283. if (scanFieldSizeX >= 20) return 20;
  2284. if (scanFieldSizeX >= 10) return 10;
  2285. if (scanFieldSizeX >= 5) return 5;
  2286. if (scanFieldSizeX >= 2) return 2;
  2287. return 1;
  2288. }
  2289. #endregion
  2290. }
  2291. }