ParticlesGridDevidePage.cs 100 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621
  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 = 70;
  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 bmap1 = fldImgAccess.CapturePic(src, rectangle);
  918. int cellWidth = dgV_ParticlesDevidePage.Columns["ParticleImage"].Width - 20;
  919. int cellHeight = dgV_ParticlesDevidePage.Rows[0].Height - 20;
  920. var ratioX = (double)cellWidth / bmap1.Width;
  921. var ratioY = (double)cellWidth / bmap1.Height;
  922. var ratio = Math.Min(ratioX, ratioY);
  923. var bmap = fldImgAccess.ScaleImageProportional(bmap1, ratio);
  924. return bmap;
  925. }
  926. return null;
  927. }
  928. /// <summary>
  929. /// 计算颗粒中心的电镜坐标
  930. /// </summary>
  931. /// <param name="resultFile"></param>
  932. /// <param name="SEMPos"></param>
  933. /// <param name="ParticlePos"></param>
  934. /// <returns></returns>
  935. public static Point CalculateParticleCenterPosition(ResultFile resultFile, Point SEMPos, Point ParticlePos)
  936. {
  937. Point point = new Point();
  938. float scanFieldSizeX = resultFile.GetScanFieldSizeX();
  939. string leftOrRight = resultFile.GetXAxisDir();
  940. string downOrUp = resultFile.GetYAxisDir();
  941. float scanFieldSizeY = resultFile.GetScanFieldSizeY();
  942. float pixelSize = resultFile.GetPixelSize();
  943. if (leftOrRight == "RIGHT_TOWARD")
  944. {
  945. point.X = (int)(SEMPos.X - scanFieldSizeX / 2 + ParticlePos.X * pixelSize);
  946. }
  947. else
  948. {
  949. point.X = (int)(SEMPos.X + scanFieldSizeX / 2 - ParticlePos.X * pixelSize);
  950. }
  951. if (downOrUp == "UP_TOWARD")
  952. {
  953. point.Y = (int)(SEMPos.Y + scanFieldSizeY / 2 - ParticlePos.Y * pixelSize);
  954. }
  955. else
  956. {
  957. point.Y = (int)(SEMPos.Y - scanFieldSizeY / 2 + ParticlePos.Y * pixelSize);
  958. }
  959. return point;
  960. }
  961. /// <summary>
  962. /// 复制选择区域
  963. /// </summary>
  964. public void CopySelected()
  965. {
  966. //复制选择区域
  967. object clipboardContent = dgV_ParticlesDevidePage.GetClipboardContent();
  968. if (clipboardContent != null)
  969. Clipboard.SetDataObject(dgV_ParticlesDevidePage.GetClipboardContent());
  970. }
  971. /// <summary>
  972. /// 复制所有
  973. /// </summary>
  974. public void CopyAll()
  975. {
  976. dgV_ParticlesDevidePage.SelectAll();
  977. Clipboard.SetDataObject(dgV_ParticlesDevidePage.GetClipboardContent());
  978. }
  979. /// <summary>
  980. /// 以图像的方式将GridView进行截图
  981. /// </summary>
  982. public void CopyImage()
  983. {
  984. int width = dgV_ParticlesDevidePage.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) + 2;
  985. int height = this.Height;
  986. using (Bitmap image = new Bitmap(width, height))
  987. {
  988. dgV_ParticlesDevidePage.DrawToBitmap(image, new Rectangle(0, 0, width, height));
  989. Clipboard.SetImage(image);
  990. }
  991. }
  992. private void dgV_ParticlesDevidePage_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
  993. {
  994. //排序中
  995. if (e.Column.Tag?.ToString() == "NumericType")
  996. {
  997. if (double.TryParse(e.CellValue1?.ToString(), out double val1) &&
  998. double.TryParse(e.CellValue2?.ToString(), out double val2))
  999. {
  1000. e.SortResult = val1.CompareTo(val2);
  1001. e.Handled = true;
  1002. }
  1003. }
  1004. }
  1005. private string ChangeHardnessColor(string hardness)
  1006. {
  1007. if (string.IsNullOrEmpty(hardness))
  1008. return "";
  1009. string str = System.Text.RegularExpressions.Regex.Replace(hardness, @"[^\d.\d]", "");
  1010. return double.TryParse(str, out double hd) && hd >= 1000 ? "#FF0000" : "";
  1011. }
  1012. private void SaveParticleslist_select()
  1013. {
  1014. ParticleData fielddata = new ParticleData(result.FilePath);
  1015. List<Particle> particles = fielddata.GetParticleAllList();
  1016. Particleslist_selecttodisplay.Clear();
  1017. for (int l = 0; l < dgV_ParticlesDevidePage.SelectedRows.Count; l++)
  1018. {
  1019. //从事先加载的Bitmap对象的Tag中取出List<string>
  1020. DataGridViewRow dgvr = dgV_ParticlesDevidePage.SelectedRows[l];
  1021. string str = " particleId= " + dgvr.Cells["particleId"].Value.ToString() + " and fieldid = " + dgvr.Cells["fieldid"].Value.ToString();
  1022. DataRow[] drs = particlesFilter.Select(str);
  1023. DataRow row = drs[0];
  1024. string subParticleString = row["SubParticles"].ToString();
  1025. int i_ls_fieldid = -1; int i_ls_particleid = -1;
  1026. if (subParticleString != "" && subParticleString != null)
  1027. {
  1028. string[] SubParticlesstrG = subParticleString.Split(',');
  1029. if (SubParticlesstrG.Length > 1)
  1030. {
  1031. string fieldid1 = SubParticlesstrG[0].Split(':')[0];
  1032. string pid1 = SubParticlesstrG[0].Split(':')[1];
  1033. i_ls_fieldid = Convert.ToInt32(fieldid1);
  1034. i_ls_particleid = Convert.ToInt32(pid1);
  1035. }
  1036. }
  1037. else
  1038. {
  1039. Bitmap ls_bp = (Bitmap)dgvr.Cells[2].Value;
  1040. List<string> list_str = (List<string>)ls_bp.Tag;
  1041. if (list_str != null)
  1042. {
  1043. i_ls_fieldid = Convert.ToInt32(list_str[0]);
  1044. i_ls_particleid = Convert.ToInt32(list_str[1]);
  1045. }
  1046. }
  1047. foreach (Particle item in particles)
  1048. {
  1049. if (i_ls_fieldid == item.FieldId && i_ls_particleid == item.ParticleId)
  1050. {
  1051. Particleslist_selecttodisplay.Add(item);
  1052. break;
  1053. }
  1054. }
  1055. }
  1056. }
  1057. public List<Particle> GetParticleslist_select()
  1058. {
  1059. return Particleslist_selecttodisplay;
  1060. }
  1061. /// <summary>
  1062. /// 获取所有颗粒的分类信息
  1063. /// </summary>
  1064. /// <returns></returns>
  1065. public DataTable GetClassificationOfAllParticles()
  1066. {
  1067. string str = "";
  1068. int sel = m_ReportApp.m_conditionChoose.m_conditionData.GetComboDownListIndexByItemName(OTSIncAReportApp.OTSSampleReportInfo.OTS_REPORT_PROP_GRID_ITEMS.PARTICE_LIST);
  1069. if (sel == (int)SelItem.analyticalParticle)
  1070. {
  1071. str = "where xrayid > -1 and typeid !=9 and typeid !=-1 and typeid !=4 and SubParticles is not 'IsSubParticle' ";
  1072. }
  1073. else if (sel == (int)SelItem.otherParticles)
  1074. {
  1075. str = "where SubParticles is not 'IsSubParticle'and(typeid =9 or typeid =-1 or typeid =4)";
  1076. }
  1077. else
  1078. {
  1079. }
  1080. DataTable table = Particledata.GetClassificationOfAllParticles(str);
  1081. return table;
  1082. }
  1083. #endregion
  1084. #region 格式处理
  1085. private void AdjustTheFormatOfTheUnitValues(int rowIndex, int gridRowIndex, int columnIndex, string columnName)
  1086. {
  1087. if (!particlesFilter.Columns.Contains(columnName)) return;
  1088. if (columnName== "Element") return;
  1089. var cellValue = particlesFilter.Rows[rowIndex][columnName];
  1090. if (cellValue == null) return;
  1091. if (double.TryParse(cellValue.ToString(), out double num))
  1092. {
  1093. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = Math.Round(num, 2);
  1094. }
  1095. else
  1096. {
  1097. dgV_ParticlesDevidePage.Rows[gridRowIndex].Cells[columnIndex].Value = cellValue.ToString();
  1098. }
  1099. }
  1100. private void SetFormCtrEnabled()
  1101. {
  1102. lnkFirst.Enabled = true;
  1103. lnkPrev.Enabled = true;
  1104. lnkNext.Enabled = true;
  1105. lnkLast.Enabled = true;
  1106. btnGo.Enabled = true;
  1107. }
  1108. /// <summary>
  1109. /// 设置DataGridView样式
  1110. /// </summary>
  1111. private void SetDataGridViewStyle()
  1112. {
  1113. //用户不能调整标题的高度
  1114. dgV_ParticlesDevidePage.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
  1115. //用户不能调整 行高
  1116. dgV_ParticlesDevidePage.AllowUserToResizeRows = false;
  1117. //点击选择整行
  1118. dgV_ParticlesDevidePage.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
  1119. //居中显示
  1120. DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle
  1121. {
  1122. Alignment = DataGridViewContentAlignment.MiddleCenter
  1123. };
  1124. dgV_ParticlesDevidePage.DefaultCellStyle = dataGridViewCellStyle1;
  1125. dgV_ParticlesDevidePage.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
  1126. //再次重覆禁用拖动表头高度,居然有效果了
  1127. dgV_ParticlesDevidePage.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
  1128. //设置grid可以复制
  1129. dgV_ParticlesDevidePage.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
  1130. //设置每列的宽度
  1131. if (dgV_ParticlesDevidePage.Columns.Count > 0)
  1132. {
  1133. dgV_ParticlesDevidePage.Columns[0].Width = 40; //第一列序号的宽度设置一下吧,要不太丑
  1134. if (dgV_ParticlesDevidePage.Columns.Count > 1)
  1135. dgV_ParticlesDevidePage.Columns[1].Width = 150;
  1136. }
  1137. //设置序号列不排序
  1138. if (dgV_ParticlesDevidePage.Columns.Count > 0)
  1139. {
  1140. dgV_ParticlesDevidePage.Columns[0].SortMode = DataGridViewColumnSortMode.NotSortable;
  1141. if (dgV_ParticlesDevidePage.Columns.Count > 1)
  1142. dgV_ParticlesDevidePage.Columns[1].SortMode = DataGridViewColumnSortMode.NotSortable;
  1143. }
  1144. //设置序号列不可以设置宽度
  1145. if (dgV_ParticlesDevidePage.Columns.Count > 0)
  1146. dgV_ParticlesDevidePage.Columns[0].Resizable = DataGridViewTriState.False;
  1147. dgV_ParticlesDevidePage.RowsDefaultCellStyle.BackColor = Color.Azure;
  1148. }
  1149. #endregion
  1150. #region 进度条
  1151. private void CloseProgress()
  1152. {
  1153. //加载完成设置鼠标为默认
  1154. this.Cursor = Cursors.Default;
  1155. string str8 = table?["str8"].ToString() ?? "完成";
  1156. if (m_frm_userprogress != null && !m_frm_userprogress.IsDisposed)
  1157. {
  1158. m_frm_userprogress.SetProgressValueAndText(100, str8);
  1159. m_frm_userprogress.Close();
  1160. }
  1161. }
  1162. private void CloseProgressIfNeeded()
  1163. {
  1164. this.Cursor = Cursors.Default;
  1165. if (m_frm_userprogress != null && !m_frm_userprogress.IsDisposed)
  1166. m_frm_userprogress.Close();
  1167. }
  1168. private void ProgressStart()
  1169. {
  1170. #region 加载显示进度条部份
  1171. this.Cursor = Cursors.WaitCursor;
  1172. m_frm_userprogress = new Frm_UserProgress();
  1173. Form ls_main_form = this.ParentForm?.ParentForm;//取出父窗体
  1174. if (ls_main_form == null)
  1175. {
  1176. m_frm_userprogress.Visible = false;
  1177. }
  1178. else
  1179. {
  1180. m_frm_userprogress.Width = (int)(MyPrimaryScreen.DESKTOP.Width / MyPrimaryScreen.ScaleX * 0.9);
  1181. m_frm_userprogress.Location = new Point(
  1182. ls_main_form.Location.X + 80,
  1183. ls_main_form.Location.Y + (int)(MyPrimaryScreen.DESKTOP.Height / MyPrimaryScreen.ScaleX) / 2);
  1184. m_frm_userprogress.Show();
  1185. m_frm_userprogress.SetProgressValueAndText(0, "Loading data of particles...");
  1186. }
  1187. #endregion
  1188. }
  1189. #endregion
  1190. #region UI事件
  1191. private void ToolStripMenuItem1_Click(object sender, EventArgs e)
  1192. {
  1193. //复制整个表
  1194. CopyAll();
  1195. }
  1196. private void ToolStripMenuItem2_Click(object sender, EventArgs e)
  1197. {
  1198. //复制选择区域
  1199. CopySelected();
  1200. }
  1201. private void toolStripMenuItem4_Click(object sender, EventArgs e)
  1202. {
  1203. //对gridview进行截图
  1204. CopyImage();
  1205. }
  1206. private void ToolStripMenuItem5_Click(object sender, EventArgs e)
  1207. {
  1208. /*注意:多数据源情况下,只获取第一个数据源的选择了多行的情况下,只获取最后一个选择行的,没有办法,这是为了符合李阳博士提出的要求*/
  1209. //先获取鼠标所选择的行里的颗粒的FieldID和ParticleID
  1210. if (dgV_ParticlesDevidePage.SelectedRows.Count == 0) return;
  1211. string i_ls_fieldid = "";
  1212. string i_ls_particleid = "";
  1213. int cou = dgV_ParticlesDevidePage.SelectedRows.Count;
  1214. DataGridViewRow dgvr = dgV_ParticlesDevidePage.SelectedRows[cou - 1];
  1215. if (dgvr.Cells[2].Value is Bitmap ls_bp && ls_bp.Tag is List<string> list_str)
  1216. {
  1217. i_ls_fieldid = list_str[0];
  1218. i_ls_particleid = list_str[1];
  1219. }
  1220. ParticleData particleData = new ParticleData(result.FilePath);
  1221. Particle particle = particleData.GetParticleByFidAndPid(i_ls_fieldid, i_ls_particleid);
  1222. //取得Field的Position,然后执行线程移动SEM到当前Field的位置
  1223. if (m_mythread == null) return;
  1224. if (m_mythread.ThreadState == ThreadState.Running ||
  1225. m_mythread.ThreadState == ThreadState.WaitSleepJoin)
  1226. {
  1227. return;
  1228. }
  1229. if (m_mythread.ThreadState == ThreadState.Stopped)
  1230. {
  1231. m_mythread = new Thread(new ParameterizedThreadStart(ControlThread_GO));
  1232. }
  1233. Point point = CalculateParticleCenterPosition(result,
  1234. new Point(particle.SEMPosX, particle.SEMPosY),
  1235. new Point(particle.PosX, particle.PosY));
  1236. //改为线程调用,先判断线程状态
  1237. m_mythread.Start(point);
  1238. }
  1239. private void ToolStripMenuItem_exportimagefile_Click(object sender, EventArgs e)
  1240. {
  1241. using (FolderBrowserDialog fbd = new FolderBrowserDialog())
  1242. {
  1243. if (fbd.ShowDialog() != DialogResult.OK) return;
  1244. m_imagefilepath = fbd.SelectedPath;
  1245. for (int i = 0; i < dgV_ParticlesDevidePage.Rows.Count; i++)
  1246. {
  1247. if (dgV_ParticlesDevidePage.Rows[i].Cells[2].Value is Bitmap ls_bp)
  1248. {
  1249. string filePath = Path.Combine(m_imagefilepath, $"{(i + 1)}.jpg");
  1250. ls_bp.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
  1251. }
  1252. }
  1253. string str9 = table?["str9"].ToString() ?? "导出完成,共导出 ";
  1254. MessageBox.Show(str9 + dgV_ParticlesDevidePage.Rows.Count.ToString());
  1255. }
  1256. }
  1257. private void testToolStripMenuItem_Click(object sender, EventArgs e)
  1258. {
  1259. // Empty method placeholder
  1260. }
  1261. private void btn_Sel_Click(object sender, EventArgs e)
  1262. {
  1263. condition = "";
  1264. if (!ValidateAndAddCondition(tBx_AreaMin.Text, "Area", ">"))
  1265. return;
  1266. if (!ValidateAndAddCondition(Tbx_AreaMax.Text, "Area", "<"))
  1267. return;
  1268. if (!string.IsNullOrWhiteSpace(tBx_AreaMin.Text) &&
  1269. !string.IsNullOrWhiteSpace(Tbx_AreaMax.Text))
  1270. {
  1271. if (!CompareInput(tBx_AreaMin.Text, Tbx_AreaMax.Text))
  1272. {
  1273. ShowErrorMessage("str11");
  1274. return;
  1275. }
  1276. }
  1277. if (!ValidateAndAddCondition(tbx_DmaxMin.Text, "DMAX", ">"))
  1278. return;
  1279. if (!ValidateAndAddCondition(tbx_DmaxMax.Text, "DMAX", "<"))
  1280. return;
  1281. if (!string.IsNullOrWhiteSpace(tbx_DmaxMin.Text) &&
  1282. !string.IsNullOrWhiteSpace(tbx_DmaxMax.Text))
  1283. {
  1284. if (!CompareInput(tbx_DmaxMin.Text, tbx_DmaxMax.Text))
  1285. {
  1286. ShowErrorMessage("str11");
  1287. return;
  1288. }
  1289. }
  1290. if (!ValidateIntegerField(tB_FieldId.Text, "FieldId"))
  1291. return;
  1292. if (!ValidateIntegerField(tB_ParticleId.Text, "ParticleId"))
  1293. return;
  1294. if (!ValidateAndAddCondition(tbx_DferretMin.Text, "DFERET", ">"))
  1295. return;
  1296. if (!ValidateAndAddCondition(tbx_DferretMax.Text, "DFERET", "<"))
  1297. return;
  1298. if (!string.IsNullOrWhiteSpace(tbx_DferretMin.Text) &&
  1299. !string.IsNullOrWhiteSpace(tbx_DferretMax.Text))
  1300. {
  1301. if (!CompareInput(tbx_DferretMin.Text, tbx_DferretMax.Text))
  1302. {
  1303. ShowErrorMessage("str11");
  1304. return;
  1305. }
  1306. }
  1307. if (!ProcessECDConditions())
  1308. return;
  1309. if (!string.IsNullOrWhiteSpace(tbx_Type.Text))
  1310. {
  1311. string[] types = tbx_Type.Text.Split('$');
  1312. condition += " and (";
  1313. for (int i = 0; i < types.Length; i++)
  1314. {
  1315. if (i == 0)
  1316. {
  1317. condition += $" TypeName = '{types[i]}'";
  1318. }
  1319. else
  1320. {
  1321. condition += $" or TypeName = '{types[i]}'";
  1322. }
  1323. }
  1324. condition += ")";
  1325. }
  1326. if (m_frm_userprogress?.IsDisposed != false)
  1327. {
  1328. ProgressStart();
  1329. }
  1330. UpdateDataGrid();
  1331. lnkFirst_Click(null, null);
  1332. SetDataGridViewStyle();
  1333. }
  1334. /// <summary>
  1335. /// 分页属性改变了。
  1336. /// </summary>
  1337. private void txtPageSize_TextChanged(object sender, EventArgs e)
  1338. {
  1339. if (!int.TryParse(txtPageNum.Text.Trim(), out int num) || num <= 0)
  1340. {
  1341. txtPageNum.Text = "1";
  1342. }
  1343. }
  1344. private void lnkFirst_Click(object sender, EventArgs e)
  1345. {
  1346. PageIndex = 1;
  1347. DrawControl(true);
  1348. }
  1349. private void lnkPrev_Click(object sender, EventArgs e)
  1350. {
  1351. PageIndex = Math.Max(1, PageIndex - 1);
  1352. DrawControl(true);
  1353. }
  1354. private void lnkNext_Click(object sender, EventArgs e)
  1355. {
  1356. PageIndex = Math.Min(PageCount, PageIndex + 1);
  1357. DrawControl(true);
  1358. }
  1359. private void lnkLast_Click(object sender, EventArgs e)
  1360. {
  1361. PageIndex = PageCount;
  1362. DrawControl(true);
  1363. }
  1364. /// <summary>
  1365. /// 跳转
  1366. /// </summary>
  1367. /// <param name="sender"></param>
  1368. /// <param name="e"></param>
  1369. private void btnGo_Click(object sender, EventArgs e)
  1370. {
  1371. if (int.TryParse(txtPageNum.Text.Trim(), out int num) && num > 0)
  1372. {
  1373. if (num > PageCount)
  1374. {
  1375. num = PageCount;
  1376. txtPageNum.Text = PageCount.ToString();
  1377. }
  1378. PageIndex = num;
  1379. DrawControl(true);
  1380. }
  1381. }
  1382. private void cbB_PageSize_SelectedIndexChanged(object sender, EventArgs e)
  1383. {
  1384. DisplayData();
  1385. }
  1386. private void EXCELToolStripMenuItem_Click(object sender, EventArgs e)
  1387. {
  1388. using (var sfd = new OTSIncAReportApp._1_UI.Control_Grids.SpectrumExportConfirmation())
  1389. {
  1390. if (sfd.ShowDialog() != DialogResult.OK) return;
  1391. if (m_frm_userprogress?.IsDisposed != false)
  1392. {
  1393. ProgressStart();
  1394. }
  1395. try
  1396. {
  1397. ExcelExport excelExport=new ExcelExport(dgV_ParticlesDevidePage,particlesFilter,Particledata, m_frm_userprogress);
  1398. excelExport.ExportToExcel(sfd);
  1399. }
  1400. finally
  1401. {
  1402. //加载完成,关闭进度条
  1403. if (m_frm_userprogress != null && !m_frm_userprogress.IsDisposed)
  1404. {
  1405. m_frm_userprogress.SetProgressValueAndText(100, "导出完成");
  1406. m_frm_userprogress.Close();
  1407. }
  1408. Cursor = Cursors.Default;
  1409. //导出完成后,打开Excel文件
  1410. if (File.Exists(sfd.FileName))
  1411. {
  1412. System.Diagnostics.Process.Start(sfd.FileName);
  1413. }
  1414. }
  1415. }
  1416. }
  1417. private void ToolStripMenuItem3_Click(object sender, EventArgs e)
  1418. {
  1419. //如果没有选中颗粒退出
  1420. if (dgV_ParticlesDevidePage.SelectedRows.Count == 0)
  1421. {
  1422. return;
  1423. }
  1424. string categoryName = GetSelectedCategoryName();
  1425. var classificationData = GetClassificationData();
  1426. using (var modifyCategoryForm = new ModifyCategoryForm(classificationData, categoryName))
  1427. {
  1428. if (modifyCategoryForm.ShowDialog() != DialogResult.OK ||
  1429. !modifyCategoryForm.DoYouWantToModifyIt)
  1430. {
  1431. return;
  1432. }
  1433. var updateParams = GetUpdateParameters(modifyCategoryForm);
  1434. HandleCategoryUpdate(updateParams);
  1435. }
  1436. }
  1437. private void ToolStripMenuItem_Delete_Particle_Click(object sender, EventArgs e)
  1438. {
  1439. string path = result.FilePath;
  1440. var fieldData = new ParticleData(result.FilePath);
  1441. List<Particle> particles = fieldData.GetParticleAllList();
  1442. DialogResult dr = MessageBox.Show("Remove all these particles permanently?",
  1443. "Tips", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
  1444. if (dr == DialogResult.OK)
  1445. {
  1446. DeleteSelectedParticles(particles);
  1447. }
  1448. }
  1449. private void btn_particletypesel_Click(object sender, EventArgs e)
  1450. {
  1451. ParticleClassificationSelect particleClassificationSelect = new ParticleClassificationSelect(this, tbx_Type.Text);
  1452. DialogResult result = particleClassificationSelect.ShowDialog();
  1453. if (result == DialogResult.OK)
  1454. {
  1455. condition = "";
  1456. tbx_Type.Text = "";
  1457. if (particleClassificationSelect.ParticleClassificationSelected != "")
  1458. {
  1459. tbx_Type.Text = particleClassificationSelect.ParticleClassificationSelected;
  1460. btn_Sel_Click(null, null);
  1461. }
  1462. }
  1463. }
  1464. private void btn_showconfig_Click(object sender, EventArgs e)
  1465. {
  1466. var p = particlesFilter; List<string> ele = new List<string>();
  1467. string elementsstr = "";
  1468. foreach (DataRow row in particlesFilter.Rows)
  1469. {
  1470. string[] strcbo = row["Element"].ToString().Split(';');
  1471. for (int j = 0; j < strcbo.Length; j++)
  1472. {
  1473. string[] str = strcbo[j].Split('-');
  1474. if (!ele.Contains(str[0]) && str[0] != "")
  1475. {
  1476. if (str[1] != "" && double.Parse(str[1]) != 0) //咨询demo后,元素含量返回值为零时一般去除此元素
  1477. { ele.Add(str[0]); }
  1478. }
  1479. }
  1480. }
  1481. foreach (var el in ele)
  1482. {
  1483. elementsstr += el.ToString() + ',';
  1484. }
  1485. if (elementsstr != "")
  1486. {
  1487. elementsstr = elementsstr.Remove(elementsstr.Length - 1, 1);
  1488. }
  1489. m_particlesGridDevidePageShowConfig = new ParticlesGridDevidePageShowConfig(m_ReportApp.m_RptConfigFile.Systype, elementsstr);
  1490. m_particlesGridDevidePageShowConfig.ShowDialog();
  1491. if (m_particlesGridDevidePageShowConfig.DialogResult == DialogResult.OK)
  1492. {
  1493. dgV_ParticlesDevidePage.Rows.Clear();
  1494. dgV_ParticlesDevidePage.Columns.Clear();
  1495. RefreshGridView();
  1496. SetDataGridViewStyle();
  1497. }
  1498. }
  1499. private void tbx_Type_Click(object sender, EventArgs e)
  1500. {
  1501. ParticleClassificationSelect particleClassificationSelect = new ParticleClassificationSelect(this, tbx_Type.Text);
  1502. DialogResult result = particleClassificationSelect.ShowDialog();
  1503. if (result == DialogResult.OK)
  1504. {
  1505. condition = "";
  1506. tbx_Type.Text = particleClassificationSelect.ParticleClassificationSelected;
  1507. string[] tr = tbx_Type.Text.Split(',');
  1508. condition += " and (";
  1509. for (int i = 0; i < tr.Length; i++)
  1510. {
  1511. if (i == 0)
  1512. {
  1513. condition += " TypeName = '" + tr[i] + "'";
  1514. }
  1515. else
  1516. {
  1517. condition += " or TypeName = '" + tr[i] + "'";
  1518. }
  1519. }
  1520. condition += ")";
  1521. if (m_frm_userprogress.IsDisposed)
  1522. {
  1523. ProgressStart();
  1524. }
  1525. UpdateDataGrid();
  1526. lnkFirst_Click(null, null);
  1527. SetDataGridViewStyle();
  1528. }
  1529. }
  1530. private void 根据相似度批量修改ToolStripMenuItem_Click(object sender, EventArgs e)
  1531. {
  1532. //如果没有选中颗粒退出
  1533. if (dgV_ParticlesDevidePage.SelectedRows.Count != 1)
  1534. {
  1535. MessageBox.Show("Please select one row!");
  1536. return;
  1537. }
  1538. var SelectRows = dgV_ParticlesDevidePage.SelectedRows;
  1539. DataGridViewRow dgvr = SelectRows[0];
  1540. Bitmap ls_bp = (Bitmap)dgvr.Cells[2].Value;
  1541. List<string> list_str = (List<string>)ls_bp.Tag;
  1542. uint[] Analysis_xray = new uint[2000];
  1543. int i_xray_id = 0;
  1544. List<Element> list_celementchemistryclr = new List<Element>();
  1545. string str = " particleId= " + dgvr.Cells["particleId"].Value.ToString() + " and fieldid = " + dgvr.Cells["fieldid"].Value.ToString();
  1546. DataRow[] drs = particlesFilter.Select(str);
  1547. DataRow row = drs[0];
  1548. string subParticleString = row["SubParticles"].ToString();
  1549. if (subParticleString != "" && subParticleString != null)
  1550. {
  1551. Particledata.GetXrayByParticleTagIDAndFieldID_ForMergeParticle(Convert.ToInt32(dgvr.Cells["particleId"].Value), Convert.ToInt32(dgvr.Cells["fieldid"].Value), out Analysis_xray);
  1552. }
  1553. else
  1554. {
  1555. 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);
  1556. }
  1557. ListOfSimilarParticles Form_listOfSimilarParticles = new ListOfSimilarParticles(this, Analysis_xray, m_ReportApp);
  1558. DialogResult result3 = Form_listOfSimilarParticles.ShowDialog();
  1559. if (result3 == DialogResult.OK)
  1560. {
  1561. UpdateDataGrid();
  1562. lnkFirst_Click(null, null);
  1563. SetDataGridViewStyle();
  1564. DataTable table = GetClassificationOfAllParticles();
  1565. if (table != null)
  1566. {
  1567. if (table.Rows.Count > 0)
  1568. {
  1569. foreach (DataRow rw in table.Rows)
  1570. {
  1571. tbx_Type.Text += rw["TypeName"].ToString() + '$';
  1572. }
  1573. }
  1574. if (tbx_Type.Text != "")
  1575. {
  1576. tbx_Type.Text = tbx_Type.Text.Remove(tbx_Type.Text.Length - 1);
  1577. }
  1578. }
  1579. dgV_ParticlesDevidePage.Focus();
  1580. }
  1581. else
  1582. {
  1583. }
  1584. }
  1585. private void dgV_ParticlesDevidePage_KeyDown(object sender, KeyEventArgs e)
  1586. {
  1587. if (e.KeyData == Keys.Delete)
  1588. {
  1589. ToolStripMenuItem_Delete_Particle_Click(null, null);
  1590. }
  1591. }
  1592. private void dgV_ParticlesDevidePage_KeyUp(object sender, KeyEventArgs e)
  1593. {
  1594. if (e.KeyData == Keys.Down)
  1595. {
  1596. dgV_ParticlesDevidePage_MouseUp(null, null);
  1597. }
  1598. if (e.KeyData == Keys.Up)
  1599. {
  1600. dgV_ParticlesDevidePage_MouseUp(null, null);
  1601. }
  1602. }
  1603. private void dgV_ParticlesDevidePage_MouseUp(object sender, MouseEventArgs e)
  1604. {
  1605. ToolStripMenuItem_SimilarityReclassification.Enabled = false;
  1606. var SelectRows = dgV_ParticlesDevidePage.SelectedRows;
  1607. if (SelectRows.Count != 0)
  1608. {
  1609. if (SelectRows.Count == 1)
  1610. {
  1611. DataGridViewRow dgvr = SelectRows[0];
  1612. Bitmap ls_bp = (Bitmap)dgvr.Cells[2].Value;
  1613. uint[] Analysis_xray = new uint[2000];
  1614. Particle particle = new Particle();
  1615. string str = " particleId= " + dgvr.Cells["particleId"].Value.ToString() + " and fieldid = " + dgvr.Cells["fieldid"].Value.ToString();
  1616. DataRow[] drs = particlesFilter.Select(str);
  1617. DataRow row = drs[0];
  1618. string subParticleString = row["SubParticles"].ToString();
  1619. particle = Particledata.GetXrayByParticleIDAndFieldID(subParticleString, Convert.ToInt32(dgvr.Cells["particleId"].Value), Convert.ToInt32(dgvr.Cells["fieldid"].Value), out Analysis_xray);
  1620. List<ShowElementInfo> list_showelementinfo = Particledata.GetShowElementInfos(particle.ElementList);
  1621. string str_IncAName = "";
  1622. str_IncAName = Convert.ToString(dgvr.Cells[1].Value);
  1623. if (particle == null)
  1624. {
  1625. return;
  1626. }
  1627. 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));
  1628. control_XRayTable1.Visible = true;
  1629. control_XRayTable1.SetXRayShowLineValue(Analysis_xray, list_showelementinfo);
  1630. control_XRayTable1.GBInfoStr = "";
  1631. control_XRayTable1.MaterialName = str_IncAName;
  1632. control_XRayTable1.List_ShowElementInfo = list_showelementinfo;
  1633. DataTable dataTable = new DataTable();
  1634. double pix = result.GetPixelSize();
  1635. int width = result.GetImageWidth();
  1636. int height = result.GetImageHeight();
  1637. Dictionary<string, List<Segment>> segsData = new Dictionary<string, List<Segment>>();
  1638. if (subParticleString == "" || subParticleString == null)
  1639. {
  1640. int fldid = Convert.ToInt32(dgvr.Cells["fieldid"].Value);
  1641. int partid = Convert.ToInt32(dgvr.Cells["particleId"].Value);
  1642. var listseg = Particledata.GetSegmentData(fldid, partid);
  1643. string key = fldid.ToString() + "_" + partid.ToString();
  1644. segsData.Add(key, listseg);
  1645. dataTable = particlesFilter.Clone();
  1646. dataTable.ImportRow(row);
  1647. }
  1648. else
  1649. {
  1650. string vs = "," + subParticleString.Replace(':', '-') + ",";
  1651. dataTable = Particledata.GetParticleAllForBig(vs);//组成拼接颗粒的子颗粒
  1652. foreach (DataRow dow in dataTable.Rows)
  1653. {
  1654. int fldid = Convert.ToInt32(dow["fieldid"]);
  1655. int partid = Convert.ToInt32(dow["particleId"]);
  1656. var listseg = Particledata.GetSegmentData(fldid, partid);
  1657. string key = dow["fieldid"].ToString() + "_" + dow["particleid"].ToString();
  1658. segsData.Add(key, listseg);
  1659. }
  1660. }
  1661. Bitmap bmap = fldImgAccess.GetBitmapForParticleAll(subParticleString, dataTable, pix, height, width);
  1662. Bitmap bmap1 = fldImgAccess.GetBitmapForParticleAllWithBlackAndWhite(subParticleString, dataTable, segsData, pix, height, width);
  1663. control_XRayTable1.SetBitmapOfPictureBox(bmap, bmap1);
  1664. Invalidate();
  1665. ToolStripMenuItem_SimilarityReclassification.Enabled = true;
  1666. }
  1667. SaveParticleslist_select();
  1668. }
  1669. }
  1670. private void dgV_ParticlesDevidePage_MouseDown(object sender, MouseEventArgs e)
  1671. {
  1672. ToolStripMenuItemDelete_Particle.Visible = true;
  1673. }
  1674. #endregion
  1675. #endregion
  1676. #region 连接电镜相关
  1677. /// <summary>
  1678. /// 移动SEM到指定位置线程函数
  1679. /// </summary>
  1680. private void ControlThread_GO(object in_obj)
  1681. {
  1682. if (m_mythread_state) return;
  1683. m_mythread_state = true;
  1684. try
  1685. {
  1686. Point sem_point = (Point)in_obj;
  1687. //第一步,连接电镜
  1688. m_OTSIncAReportGridsFun?.Connection_ForParticlesGrid();
  1689. Thread.Sleep(500);
  1690. //第二步,移动到指定位置,先读取再设置
  1691. if (m_OTSIncAReportGridsFun?.m_SEMConnectionState == true)
  1692. {
  1693. m_OTSIncAReportGridsFun.MoveSemToPointXY_ForParticlesGrid(sem_point.X, sem_point.Y);
  1694. }
  1695. Thread.Sleep(1500);
  1696. }
  1697. finally
  1698. {
  1699. m_mythread_state = false;
  1700. }
  1701. }
  1702. #endregion
  1703. #region 类别修改相关
  1704. /// <summary>
  1705. /// 读取标准库的ClassifySTD表
  1706. /// </summary>
  1707. /// <param name="a_address"></param>
  1708. /// <returns></returns>
  1709. private DataTable ReadClassification(string a_address, string STDName)
  1710. {
  1711. DataTable dt_STDGroups = new DataTable();
  1712. DataTable dt_ClassifySTD = new DataTable();
  1713. DataTable dt_IncAData = new DataTable();
  1714. var systype = m_ReportApp.m_RptConfigFile.Systype;
  1715. if (systype == OTS_SysType_ID.IncA)
  1716. {
  1717. dt_ClassifySTD.Columns.Add("STDId");
  1718. dt_ClassifySTD.Columns.Add("StrName");
  1719. dt_ClassifySTD.Columns.Add("Color");
  1720. dt_ClassifySTD.Columns.Add("KeyElementList");
  1721. dt_ClassifySTD.Columns.Add("SubElementList");
  1722. dt_ClassifySTD.Columns.Add("UsingImgPropertyList");
  1723. dt_ClassifySTD.Columns.Add("UsingOtherPropertyList");
  1724. dt_ClassifySTD.Columns.Add("Expression");
  1725. dt_ClassifySTD.Columns.Add("Hardness");
  1726. dt_ClassifySTD.Columns.Add("Density");
  1727. dt_ClassifySTD.Columns.Add("Electrical_conductivity");
  1728. dt_ClassifySTD.Columns.Add("BSE");
  1729. dt_ClassifySTD.Columns.Add("Formula");
  1730. dt_ClassifySTD.Columns.Add("Element");
  1731. dt_ClassifySTD.Columns.Add("IfElementAnalysis");
  1732. dt_ClassifySTD.Columns.Add("ListNum");
  1733. dt_ClassifySTD.Columns.Add("GroupId");
  1734. dt_ClassifySTD.Columns.Add("GroupName");
  1735. dt_ClassifySTD.Columns.Add("GroupColor");
  1736. DataTable da = Particledata.GetParticleListForParticlSizeID("area", "");
  1737. for (int i = 0; i < da.Rows.Count; i++)
  1738. {
  1739. if (Convert.ToInt64(da.Rows[i]["TypeId"]) > 9)
  1740. {
  1741. DataRow newRow = dt_ClassifySTD.NewRow();
  1742. newRow["STDId"] = da.Rows[i]["TypeId"];
  1743. newRow["StrName"] = da.Rows[i]["TypeName"];
  1744. newRow["Color"] = da.Rows[i]["TypeColor"];
  1745. newRow["GroupId"] = da.Rows[i]["GroupId"];
  1746. newRow["GroupName"] = da.Rows[i]["GroupName"];
  1747. newRow["GroupColor"] = da.Rows[i]["GroupColor"];
  1748. dt_ClassifySTD.Rows.Add(newRow);
  1749. }
  1750. }
  1751. }
  1752. else
  1753. {
  1754. SqLiteHelper sh_STDGroups = new SqLiteHelper("data source='" + a_address + "\\" + STDName + ".db" + "'");
  1755. dt_STDGroups = sh_STDGroups.ExecuteQuery("select * from STDGroups");
  1756. SqLiteHelper sh_ClassifySTD = new SqLiteHelper("data source='" + a_address + "\\" + STDName + ".db" + "'");
  1757. dt_ClassifySTD = sh_ClassifySTD.ExecuteQuery("select * from ClassifySTD");
  1758. dt_ClassifySTD.Columns.Add("GroupName");
  1759. dt_ClassifySTD.Columns.Add("GroupColor");
  1760. for (int i = 0; i < dt_ClassifySTD.Rows.Count; i++)
  1761. {
  1762. for (int a = 0; a < dt_STDGroups.Rows.Count; a++)
  1763. {
  1764. if (dt_ClassifySTD.Rows[i]["GroupId"].ToString() == dt_STDGroups.Rows[a]["id"].ToString())
  1765. {
  1766. dt_ClassifySTD.Rows[i]["GroupName"] = dt_STDGroups.Rows[a]["name"].ToString();
  1767. dt_ClassifySTD.Rows[i]["GroupColor"] = dt_STDGroups.Rows[a]["color"].ToString();
  1768. continue;
  1769. }
  1770. }
  1771. }
  1772. SqLiteHelper sh_Inclusion = new SqLiteHelper("data source='" + a_address + "\\FIELD_FILES\\Inclusion.db" + "'");
  1773. dt_IncAData = sh_Inclusion.ExecuteQuery("select * from IncAData");
  1774. for (int i = 0; i < dt_IncAData.Rows.Count; i++)
  1775. {
  1776. if (Convert.ToInt64(dt_IncAData.Rows[i]["TypeId"]) > 50000)
  1777. {
  1778. DataRow newRow = dt_ClassifySTD.NewRow();
  1779. newRow["STDId"] = dt_IncAData.Rows[i]["TypeId"];
  1780. newRow["StrName"] = dt_IncAData.Rows[i]["TypeName"];
  1781. newRow["Color"] = dt_IncAData.Rows[i]["TypeColor"];
  1782. newRow["GroupId"] = dt_IncAData.Rows[i]["GroupId"];
  1783. newRow["GroupName"] = dt_IncAData.Rows[i]["GroupName"];
  1784. newRow["GroupColor"] = dt_IncAData.Rows[i]["GroupColor"];
  1785. dt_ClassifySTD.Rows.Add(newRow);
  1786. }
  1787. }
  1788. }
  1789. DataRow newRowInvalid = dt_ClassifySTD.NewRow();
  1790. newRowInvalid["STDId"] = -1;
  1791. newRowInvalid["StrName"] = "Invalid";
  1792. newRowInvalid["Color"] = "#000000";
  1793. newRowInvalid["GroupId"] = -1;
  1794. newRowInvalid["GroupName"] = "Invalid";
  1795. newRowInvalid["GroupColor"] = "#000000";
  1796. dt_ClassifySTD.Rows.Add(newRowInvalid);
  1797. return dt_ClassifySTD;
  1798. }
  1799. private string GetSelectedCategoryName()
  1800. {
  1801. if (dgV_ParticlesDevidePage.SelectedRows.Count > 0)
  1802. {
  1803. DataGridViewRow lastRow = dgV_ParticlesDevidePage.SelectedRows[
  1804. dgV_ParticlesDevidePage.SelectedRows.Count - 1];
  1805. return lastRow.Cells[1].Value?.ToString() ?? "";
  1806. }
  1807. return "";
  1808. }
  1809. private DataTable GetClassificationData()
  1810. {
  1811. string[] resultParts = result.GetSTDName().Split('.');
  1812. return ReadClassification(result.FilePath, resultParts[0]);
  1813. }
  1814. private List<string> GetUpdateParameters(ModifyCategoryForm form)
  1815. {
  1816. return new List<string>
  1817. {
  1818. form.OutTypeAndName[0], // TypeId
  1819. form.OutTypeAndName[1], // TypeName
  1820. form.OutTypeAndName[2], // TypeColor
  1821. form.OutTypeAndName[3], // GroupName
  1822. form.OutTypeAndName[4], // GroupID
  1823. form.OutTypeAndName[5] // GroupColor
  1824. };
  1825. }
  1826. private void HandleCategoryUpdate(List<string> updateParams)
  1827. {
  1828. if (dgV_ParticlesDevidePage.SelectedRows.Count == 1)
  1829. {
  1830. HandleSingleRowUpdate(updateParams);
  1831. }
  1832. else
  1833. {
  1834. HandleMultipleRowsUpdate(updateParams);
  1835. }
  1836. RefreshAfterUpdate();
  1837. }
  1838. private void HandleSingleRowUpdate(List<string> updateParams)
  1839. {
  1840. DialogResult result = MessageBox.Show("是否寻找相似颗粒并重命名?", "Tip",
  1841. MessageBoxButtons.YesNo);
  1842. if (result == DialogResult.Yes)
  1843. {
  1844. HandleSimilarParticleSearch(updateParams);
  1845. }
  1846. else
  1847. {
  1848. ExecuteBatchUpdate(updateParams);
  1849. }
  1850. }
  1851. private void HandleSimilarParticleSearch(List<string> updateParams)
  1852. {
  1853. int sel = m_ReportApp.m_conditionChoose.m_conditionData
  1854. .GetComboDownListIndexByItemName(
  1855. OTSIncAReportApp.OTSSampleReportInfo.OTS_REPORT_PROP_GRID_ITEMS.PARTICE_LIST);
  1856. if (sel == (int)SelItem.MergeParticles)
  1857. {
  1858. ExecuteBatchUpdate(updateParams);
  1859. return;
  1860. }
  1861. uint[] analysisXray = new uint[2000];
  1862. if (dgV_ParticlesDevidePage.SelectedRows.Count == 1)
  1863. {
  1864. DataGridViewRow row = dgV_ParticlesDevidePage.SelectedRows[0];
  1865. ReportFun.GetXrayByParticleTagIDAndFieldID_ForDrawDistrbutionImageAndBSE(
  1866. Convert.ToInt32(row.Cells["particleId"].Value),
  1867. Convert.ToInt32(row.Cells["fieldid"].Value),
  1868. out analysisXray,
  1869. out int _, // i_xray_id
  1870. out List<Element> _); // list_celementchemistryclr
  1871. }
  1872. using (var form = new ListOfSimilarParticles(this, analysisXray, updateParams, m_ReportApp))
  1873. {
  1874. if (form.ShowDialog() != DialogResult.OK)
  1875. {
  1876. ExecuteBatchUpdate(updateParams);
  1877. }
  1878. }
  1879. }
  1880. private void HandleMultipleRowsUpdate(List<string> updateParams)
  1881. {
  1882. ExecuteBatchUpdate(updateParams);
  1883. }
  1884. private void ExecuteBatchUpdate(List<string> updateParams)
  1885. {
  1886. var cmdList = new List<KeyValuePair<string, SQLiteParameter[]>>();
  1887. foreach (DataGridViewRow row in dgV_ParticlesDevidePage.SelectedRows)
  1888. {
  1889. UpdateGridRow(row, updateParams[1]); // TypeName
  1890. if (row.Cells[2].Value is Bitmap bitmap && bitmap.Tag is List<string> tagList)
  1891. {
  1892. var particleIds = new List<int>
  1893. {
  1894. Convert.ToInt32(tagList[0]), // fieldId
  1895. Convert.ToInt32(tagList[1]) // particleId
  1896. };
  1897. var cmd = Particledata.GetUpdataAIncACmd(particleIds, updateParams);
  1898. cmdList.Add(cmd);
  1899. }
  1900. row.Cells[1].Value = updateParams[1]; // Update TypeName in grid
  1901. }
  1902. Particledata.ExecuteNonQueryBatch(cmdList);
  1903. }
  1904. private void UpdateGridRow(DataGridViewRow row, string typeName)
  1905. {
  1906. row.Cells[1].Value = typeName;
  1907. }
  1908. private void RefreshAfterUpdate()
  1909. {
  1910. UpdateDataGrid();
  1911. lnkFirst_Click(null, null);
  1912. SetDataGridViewStyle();
  1913. UpdateTypeTextBox();
  1914. dgV_ParticlesDevidePage.Focus();
  1915. }
  1916. private void UpdateTypeTextBox()
  1917. {
  1918. tbx_Type.Text = "";
  1919. DataTable table = GetClassificationOfAllParticles();
  1920. if (table?.Rows.Count > 0)
  1921. {
  1922. tbx_Type.Text = string.Join("$", table.AsEnumerable()
  1923. .Select(row => row["TypeName"].ToString()));
  1924. }
  1925. }
  1926. #endregion
  1927. #region 删除颗粒相关\备份
  1928. private void DeleteSelectedParticles(List<Particle> particles)
  1929. {
  1930. var deletedParticles = new List<Particle>();
  1931. foreach (DataGridViewRow row in dgV_ParticlesDevidePage.SelectedRows)
  1932. {
  1933. if (row.Cells[2].Value is Bitmap bitmap && bitmap.Tag is List<string> tagList)
  1934. {
  1935. int fieldId = Convert.ToInt32(tagList[0]);
  1936. int particleId = Convert.ToInt32(tagList[1]);
  1937. Particle particleToDelete = particles.FirstOrDefault(p =>
  1938. p.FieldId == fieldId && p.ParticleId == particleId);
  1939. if (particleToDelete != null &&
  1940. DeleteParticlesFromSTDDb(particleToDelete.ParticleId, particleToDelete.FieldId))
  1941. {
  1942. RemoveParticleFromDataTable(particleToDelete);
  1943. deletedParticles.Add(particleToDelete);
  1944. }
  1945. else
  1946. {
  1947. MessageBox.Show("Delete failed");
  1948. break;
  1949. }
  1950. }
  1951. }
  1952. UpdateUIAfterDeletion(deletedParticles.Count);
  1953. //SynchronizeParticleDeletion(deletedParticles);
  1954. }
  1955. private void RemoveParticleFromDataTable(Particle particle)
  1956. {
  1957. for (int i = particlesAll.Rows.Count - 1; i >= 0; i--)
  1958. {
  1959. if (particlesAll.Rows[i]["Fieldid"].ToString() == particle.FieldId.ToString() &&
  1960. particlesAll.Rows[i]["Particleid"].ToString() == particle.ParticleId.ToString())
  1961. {
  1962. particlesAll.Rows.RemoveAt(i);
  1963. break;
  1964. }
  1965. }
  1966. }
  1967. private void UpdateUIAfterDeletion(int deletedCount)
  1968. {
  1969. RecordCount = recordCount - deletedCount;
  1970. lblTotalCount.Text = RecordCount.ToString();
  1971. // Remove rows from grid (in reverse order to avoid index issues)
  1972. var rowsToRemove = dgV_ParticlesDevidePage.SelectedRows.Cast<DataGridViewRow>().ToList();
  1973. foreach (var row in rowsToRemove)
  1974. {
  1975. dgV_ParticlesDevidePage.Rows.Remove(row);
  1976. }
  1977. if (dgV_ParticlesDevidePage.Rows.Count == 0)
  1978. {
  1979. DisplayData();
  1980. }
  1981. else
  1982. {
  1983. // Update row numbers
  1984. for (int j = 0; j < dgV_ParticlesDevidePage.Rows.Count; j++)
  1985. {
  1986. dgV_ParticlesDevidePage.Rows[j].Cells[0].Value =
  1987. (pageSize * (PageIndex - 1) + j + 1).ToString();
  1988. }
  1989. }
  1990. }
  1991. private void SynchronizeParticleDeletion(List<Particle> deletedParticles)
  1992. {
  1993. if (m_ReportApp.im_Control_DrawDistrbutionImageAndBSE != null)
  1994. {
  1995. m_ReportApp.im_Control_DrawDistrbutionImageAndBSE.DeletesParticlesSynchronously(deletedParticles);
  1996. }
  1997. else
  1998. {
  1999. using (var control = new OTSIncAReportGraph.Controls.Control_DrawDistrbutionImageAndBSE(m_ReportApp))
  2000. {
  2001. foreach (var particle in deletedParticles)
  2002. {
  2003. control.DeleteParticlesFromSTDDb(particle.ParticleId, particle.FieldId);
  2004. }
  2005. }
  2006. }
  2007. }
  2008. private bool DeleteParticlesFromSTDDb(int particleId, int fieldId)
  2009. {
  2010. if (!CheckAndCreateBackup())
  2011. return false;
  2012. //防止为空校验判断
  2013. if (result.GetList_OTSField() == null)
  2014. return false;
  2015. try
  2016. {
  2017. //Particle particle = result.GetList_OTSField()
  2018. // .Find(x => x.FieldID == fieldId)?
  2019. // .ParticleList.Find(x => x.ParticleId == particleId);
  2020. //if (particle == null)
  2021. // return false;
  2022. var particleData = new ParticleData(result.FilePath);
  2023. return particleData.DeleteFromData(
  2024. Convert.ToString(fieldId),
  2025. Convert.ToString(particleId));
  2026. }
  2027. catch (Exception ex)
  2028. {
  2029. log.Error($"Error deleting particle: {ex.Message}");
  2030. return false;
  2031. }
  2032. }
  2033. private bool CheckAndCreateBackup()
  2034. {
  2035. bool backupExists = Enumerable.Range(1, 200).Any(i =>
  2036. Directory.Exists(Path.Combine(result.FilePath, "FIELD_FILES", "Backups" + i)));
  2037. if (!backupExists)
  2038. {
  2039. return BackupDatabase();
  2040. }
  2041. return true;
  2042. }
  2043. private bool BackupDatabase()
  2044. {
  2045. try
  2046. {
  2047. //创建备份数据库文件夹
  2048. string sourcePath = Path.Combine(result.FilePath, "FIELD_FILES", "Inclusion.db");
  2049. string sourceName = "Inclusion.db";
  2050. string folderPath = Path.Combine(result.FilePath, "FIELD_FILES", "Backups");
  2051. string backupFolder = "";
  2052. for (int i = 1; i <= 200; i++)
  2053. {
  2054. string currentPath = Path.Combine(folderPath, i.ToString());
  2055. if (!Directory.Exists(currentPath))
  2056. {
  2057. Directory.CreateDirectory(currentPath);
  2058. backupFolder = currentPath;
  2059. break;
  2060. }
  2061. }
  2062. if (string.IsNullOrEmpty(backupFolder))
  2063. {
  2064. return false;
  2065. }
  2066. //复制数据库文件
  2067. string targetPath = Path.Combine(backupFolder, sourceName);
  2068. File.Copy(sourcePath, targetPath, true);
  2069. return true;
  2070. }
  2071. catch (Exception ex)
  2072. {
  2073. log.Error($"Error backing up database: {ex.Message}");
  2074. return false;
  2075. }
  2076. }
  2077. #endregion
  2078. #region 报表输出
  2079. /// <summary>
  2080. ///
  2081. /// </summary>
  2082. /// <param name="str_resultPath"></param>
  2083. /// <param name="dataTable"></param>
  2084. /// <param name="vs"></param>
  2085. /// <param name="dt_FIeld"></param>
  2086. public void Out_MarkParticleRectangleOnFieldFile(string str_resultPath, DataTable dataTable,
  2087. out List<string> vs, out DataTable dt_FIeld)
  2088. {
  2089. Init();
  2090. var fieldIds = ExtractFieldIds(dataTable);
  2091. string str_path_FIELD_FILES = Path.Combine(str_resultPath, "FIELD_FILES");
  2092. dt_FIeld = new DataTable();
  2093. vs = new List<string>();
  2094. ResultFile resfile = m_ReportApp.m_rstDataMgr.ResultFilesList[
  2095. m_ReportApp.m_rstDataMgr.GetWorkingResultId()];
  2096. float pixelSize = resfile.GetPixelSize();
  2097. float scanFieldSizeX = resfile.GetScanFieldSizeX();
  2098. int gauge = RulerSelection(scanFieldSizeX);
  2099. float rulerPixels = gauge / pixelSize;
  2100. var fieldData = new FieldData(resfile.FilePath);
  2101. DataTable dt_AllParticle = fieldData.GetAllParticle_DataTable();
  2102. var directoryInfo = new DirectoryInfo(str_path_FIELD_FILES);
  2103. if (directoryInfo.Exists)
  2104. {
  2105. ProcessFieldFiles(directoryInfo, fieldIds, dataTable, dt_AllParticle,
  2106. rulerPixels, gauge, ref dt_FIeld, vs);
  2107. }
  2108. }
  2109. private List<string> ExtractFieldIds(DataTable dataTable)
  2110. {
  2111. return dataTable.AsEnumerable()
  2112. .Where(row => Convert.ToInt32(row["TypeId"]) > 9)
  2113. .Take(10)
  2114. .Select(row => row["Fieldid"].ToString())
  2115. .Distinct()
  2116. .ToList();
  2117. }
  2118. private void ProcessFieldFiles(DirectoryInfo directoryInfo, List<string> fieldIds,
  2119. DataTable dataTable, DataTable allParticles, float rulerPixels, int gauge,
  2120. ref DataTable dt_FIeld, List<string> vs)
  2121. {
  2122. var fieldFiles = directoryInfo.GetFiles("Field*.bmp")
  2123. .ToDictionary(f => GetFieldIdFromFile(f.Name), f => f,
  2124. StringComparer.OrdinalIgnoreCase);
  2125. var resultTable = CreateFieldDataTable();
  2126. foreach (string fieldId in fieldIds.Where(id => fieldFiles.ContainsKey(id)))
  2127. {
  2128. var file = fieldFiles[fieldId];
  2129. int count = dataTable.AsEnumerable()
  2130. .Count(row => row["fieldid"].ToString() == fieldId);
  2131. DataRow dr = resultTable.NewRow();
  2132. dr["fieldid"] = $" fieldid = {fieldId}";
  2133. dr["cunt"] = count;
  2134. dr["fieldName"] = file.Name;
  2135. dr["fieldFullName"] = file.FullName;
  2136. dr["id"] = fieldId;
  2137. resultTable.Rows.Add(dr);
  2138. }
  2139. dt_FIeld = resultTable.Copy();
  2140. dt_FIeld.Columns.Add("Field_pic", typeof(Bitmap));
  2141. ProcessFieldImages(allParticles, rulerPixels, gauge, dt_FIeld, vs);
  2142. }
  2143. private string GetFieldIdFromFile(string fileName)
  2144. {
  2145. string nameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
  2146. return nameWithoutExtension.Length > 5 ?
  2147. nameWithoutExtension.Substring(5) : nameWithoutExtension;
  2148. }
  2149. private DataTable CreateFieldDataTable()
  2150. {
  2151. var dt = new DataTable();
  2152. dt.Columns.Add("fieldid");
  2153. dt.Columns.Add("id");
  2154. dt.Columns.Add("fieldName");
  2155. dt.Columns.Add("cunt", typeof(int));
  2156. dt.Columns.Add("fieldFullName");
  2157. return dt;
  2158. }
  2159. private void ProcessFieldImages(DataTable allParticles, float rulerPixels, int gauge,
  2160. DataTable dt_FIeld, List<string> vs)
  2161. {
  2162. var particleGroups = allParticles.AsEnumerable()
  2163. .GroupBy(row => row["fieldid"].ToString())
  2164. .ToDictionary(g => g.Key, g => g.ToList());
  2165. foreach (DataRow row in dt_FIeld.Rows.Cast<DataRow>().ToList())
  2166. {
  2167. string fieldId = row["id"].ToString();
  2168. if (!particleGroups.ContainsKey(fieldId) ||
  2169. particleGroups[fieldId].Count == 0)
  2170. continue;
  2171. vs.Add(fieldId);
  2172. try
  2173. {
  2174. using (var img = Image.FromFile(row["fieldFullName"].ToString()))
  2175. {
  2176. using (var fieldBitmap = new Bitmap(img.Width, img.Height,
  2177. System.Drawing.Imaging.PixelFormat.Format32bppArgb))
  2178. {
  2179. DrawBaseImage(img, fieldBitmap);
  2180. MarkParticlesOnImage(particleGroups[fieldId], fieldBitmap,
  2181. row, fieldId, rulerPixels, gauge);
  2182. }
  2183. }
  2184. }
  2185. catch (Exception ex)
  2186. {
  2187. log.Error($"Error processing field image: {ex.Message}");
  2188. }
  2189. }
  2190. }
  2191. private void DrawBaseImage(Image sourceImage, Bitmap targetBitmap)
  2192. {
  2193. using (Graphics g = Graphics.FromImage(targetBitmap))
  2194. {
  2195. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  2196. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  2197. g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
  2198. g.DrawImage(sourceImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height));
  2199. }
  2200. }
  2201. private void MarkParticlesOnImage(List<DataRow> particles, Bitmap fieldBitmap,
  2202. DataRow fieldRow, string fieldId, float rulerPixels, int gauge)
  2203. {
  2204. foreach (DataRow particleRow in particles)
  2205. {
  2206. string particleId = particleRow["particleid"].ToString();
  2207. var rectangle = new Rectangle(
  2208. Convert.ToInt32(particleRow["RectLeft"]),
  2209. Convert.ToInt32(particleRow["RectTop"]),
  2210. Convert.ToInt32(particleRow["RectWidth"]),
  2211. Convert.ToInt32(particleRow["RectHeight"])
  2212. );
  2213. MarkParticleOnImage(fieldBitmap, rectangle, fieldId, particleId);
  2214. }
  2215. using (var rulerBitmap = DrawRuler(fieldBitmap, (int)(rulerPixels / 2), 2,
  2216. $"{gauge / 2}μm"))
  2217. {
  2218. fieldRow["Field_pic"] = new Bitmap(rulerBitmap);
  2219. }
  2220. }
  2221. private void MarkParticleOnImage(Bitmap fieldBitmap, Rectangle rectangle,
  2222. string fieldId, string particleId)
  2223. {
  2224. using (Graphics g = Graphics.FromImage(fieldBitmap))
  2225. using (var pen = new Pen(Color.Aquamarine))
  2226. {
  2227. g.DrawRectangle(pen, rectangle);
  2228. int textX = rectangle.X + rectangle.Width > fieldBitmap.Width - 10 ?
  2229. rectangle.X - 10 : rectangle.X + rectangle.Width;
  2230. using (var font = new Font("黑体", 8))
  2231. using (var brush = new SolidBrush(Color.Aqua))
  2232. {
  2233. g.DrawString($"{fieldId} {particleId}", font, brush,
  2234. new PointF(textX, rectangle.Y));
  2235. }
  2236. }
  2237. }
  2238. /// <summary>
  2239. /// 在图片上绘制标尺
  2240. /// </summary>
  2241. /// <param name="bitmap">图片</param>
  2242. /// <param name="lineLength">线长(像素)</param>
  2243. /// <param name="lineWidth">线宽(像素)</param>
  2244. /// <param name="text">显示文本</param>
  2245. /// <returns></returns>
  2246. private Bitmap DrawRuler(Bitmap bitmap, int lineLength, int lineWidth, string text)
  2247. {
  2248. if (bitmap == null)
  2249. throw new ArgumentNullException(nameof(bitmap));
  2250. var rgbBitmap = new Bitmap(bitmap.Width, bitmap.Height);
  2251. using (Graphics graphics = Graphics.FromImage(rgbBitmap))
  2252. {
  2253. graphics.DrawImage(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
  2254. Color color = Color.LimeGreen;
  2255. using (var pen = new Pen(color, lineWidth))
  2256. using (var font = new Font("Arial", 20, GraphicsUnit.Pixel))
  2257. using (var brush = new SolidBrush(color))
  2258. {
  2259. var stringFormat = new StringFormat
  2260. {
  2261. Alignment = StringAlignment.Center,
  2262. LineAlignment = StringAlignment.Center
  2263. };
  2264. int startX = 20;
  2265. int startY = bitmap.Height - 30;
  2266. graphics.DrawLine(pen, startX, startY, startX + lineLength, startY);
  2267. graphics.DrawString(text, font, brush,
  2268. new PointF(startX + lineLength / 2, startY - 20), stringFormat);
  2269. }
  2270. }
  2271. return rgbBitmap;
  2272. }
  2273. private int RulerSelection(float scanFieldSizeX)
  2274. {
  2275. // 根据扫描场尺寸选择合适的标尺单位
  2276. if (scanFieldSizeX >= 1000) return 1000;
  2277. if (scanFieldSizeX >= 500) return 500;
  2278. if (scanFieldSizeX >= 200) return 200;
  2279. if (scanFieldSizeX >= 100) return 100;
  2280. if (scanFieldSizeX >= 50) return 50;
  2281. if (scanFieldSizeX >= 20) return 20;
  2282. if (scanFieldSizeX >= 10) return 10;
  2283. if (scanFieldSizeX >= 5) return 5;
  2284. if (scanFieldSizeX >= 2) return 2;
  2285. return 1;
  2286. }
  2287. #endregion
  2288. }
  2289. }