ParticlesGridDevidePage.cs 100 KB

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