RecipeViewModel.cs 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722
  1. using Aitex.Core.Common.DeviceData;
  2. using Aitex.Core.RT.IOCore;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.UI.View.Common;
  5. using MECF.Framework.Common.DataCenter;
  6. using MECF.Framework.Common.OperationCenter;
  7. using Microsoft.VisualBasic;
  8. using Newtonsoft.Json;
  9. using Newtonsoft.Json.Linq;
  10. using Prism.Commands;
  11. using Prism.Mvvm;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Collections.ObjectModel;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Reflection;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. using System.Windows;
  21. using System.Windows.Controls;
  22. using System.Windows.Data;
  23. using System.Windows.Input;
  24. using System.Windows.Media;
  25. using System.Xml;
  26. using Venus_Core;
  27. using Venus_Core.Attributes;
  28. using Venus_MainPages.PMs;
  29. using Venus_MainPages.Unity;
  30. using Venus_MainPages.Views;
  31. using Venus_Themes.UserControls;
  32. using WPF.Themes.UserControls;
  33. using MessageBox = System.Windows.MessageBox;
  34. using RecipeStep = Venus_Core.RecipeStep;
  35. namespace Venus_MainPages.ViewModels
  36. {
  37. internal class RecipeViewModel : BindableBase
  38. {
  39. #region 私有字段
  40. public string ModuleName = "PMA";
  41. private string m_CurrentRecipeName;
  42. private UiRecipeManager m_uiRecipeManager = new UiRecipeManager();
  43. private RecipeView recipeView;
  44. private TreeView treeViewRcpList;
  45. private Recipe m_currentRecipe;
  46. private string m_recipeType;
  47. private bool firstLoad = true;
  48. private WrapPanel headWrapPanel;
  49. private int copyIndex = -1;
  50. private List<string> EPDCfgList = new List<string>();
  51. private EPDType currentEPDType = EPDType.None;
  52. private JetChamber currentChamber;
  53. private bool isInstalledEPD;
  54. private bool m_IsFrozen;
  55. private bool m_PMAIsInstalled;
  56. private bool m_PMBIsInstalled;
  57. private bool m_PMCIsInstalled;
  58. private bool m_PMDIsInstalled;
  59. private List<string> moduleList = new List<string>();
  60. TreeViewFileItem selectedItem;
  61. private string typeFolder = "";
  62. private bool m_HeadExpand = true;
  63. private Grid leftGrid;
  64. private Grid rightGrid;
  65. private int controlHeight = 24;
  66. #endregion
  67. #region 属性
  68. public bool HeadExpand
  69. {
  70. get { return m_HeadExpand; }
  71. set { SetProperty(ref m_HeadExpand, value); }
  72. }
  73. public string CurrentRecipeName
  74. {
  75. get { return m_CurrentRecipeName; }
  76. set { SetProperty(ref m_CurrentRecipeName, value); }
  77. }
  78. public Recipe CurrentRecipe
  79. {
  80. get { return m_currentRecipe; }
  81. set
  82. {
  83. m_currentRecipe = value;
  84. RecipeType = m_currentRecipe?.Header?.Type.ToString();
  85. }
  86. }
  87. public string RecipeType
  88. {
  89. get { return m_recipeType; }
  90. set { SetProperty(ref m_recipeType, value); }
  91. }
  92. public bool IsFrozen
  93. {
  94. get { return m_IsFrozen; }
  95. set { SetProperty(ref m_IsFrozen, value); }
  96. }
  97. public bool PMAIsInstalled
  98. {
  99. get { return m_PMAIsInstalled; }
  100. set { SetProperty(ref m_PMAIsInstalled, value); }
  101. }
  102. public bool PMBIsInstalled
  103. {
  104. get { return m_PMBIsInstalled; }
  105. set { SetProperty(ref m_PMBIsInstalled, value); }
  106. }
  107. public bool PMCIsInstalled
  108. {
  109. get { return m_PMCIsInstalled; }
  110. set { SetProperty(ref m_PMCIsInstalled, value); }
  111. }
  112. public bool PMDIsInstalled
  113. {
  114. get { return m_PMDIsInstalled; }
  115. set { SetProperty(ref m_PMDIsInstalled, value); }
  116. }
  117. #endregion
  118. #region 命令
  119. private DelegateCommand<Object> _MouseRightButtonDownCommand;
  120. public DelegateCommand<Object> MouseRightButtonDownCommand =>
  121. _MouseRightButtonDownCommand ?? (_MouseRightButtonDownCommand = new DelegateCommand<Object>(OnMouseRightButtonDown));
  122. private DelegateCommand<Object> _LoadedCommand;
  123. public DelegateCommand<Object> LoadedCommand =>
  124. _LoadedCommand ?? (_LoadedCommand = new DelegateCommand<Object>(OnLoaded));
  125. private DelegateCommand _SaveRecipeCommand;
  126. public DelegateCommand SaveRecipeCommand =>
  127. _SaveRecipeCommand ?? (_SaveRecipeCommand = new DelegateCommand(OnSaveRecipe));
  128. private DelegateCommand<object> _SaveToRecipeCommand;
  129. public DelegateCommand<object> SaveToRecipeCommand =>
  130. _SaveToRecipeCommand ?? (_SaveToRecipeCommand = new DelegateCommand<object>(OnSaveToRecipe));
  131. private DelegateCommand _AddStepCommand;
  132. public DelegateCommand AddStepCommand =>
  133. _AddStepCommand ?? (_AddStepCommand = new DelegateCommand(OnAddStep));
  134. private DelegateCommand _DeleteStepCommand;
  135. public DelegateCommand DeleteStepCommand =>
  136. _DeleteStepCommand ?? (_DeleteStepCommand = new DelegateCommand(OnDeleteStep));
  137. private DelegateCommand _RefreshCommand;
  138. public DelegateCommand RefreshCommand =>
  139. _RefreshCommand ?? (_RefreshCommand = new DelegateCommand(OnRefresh));
  140. private DelegateCommand _ExpandCommand;
  141. public DelegateCommand ExpandCommand =>
  142. _ExpandCommand ?? (_ExpandCommand = new DelegateCommand(OnExpand));
  143. private DelegateCommand _UnloadCommand;
  144. public DelegateCommand UnloadCommand =>
  145. _UnloadCommand ?? (_UnloadCommand = new DelegateCommand(OnUnload));
  146. private DelegateCommand _ClearRecipeCommand;
  147. public DelegateCommand ClearRecipeCommand =>
  148. _ClearRecipeCommand ?? (_ClearRecipeCommand = new DelegateCommand(OnClearRecipe));
  149. private DelegateCommand<Object> _MouseLeftButtonDownCommand;
  150. public DelegateCommand<Object> MouseLeftButtonDownCommand =>
  151. _MouseLeftButtonDownCommand ?? (_MouseLeftButtonDownCommand = new DelegateCommand<Object>(OnMouseLeftButtonDown));
  152. #endregion
  153. #region 命令方法
  154. private void OnAddStep()
  155. {
  156. if (CurrentRecipe != null)
  157. {
  158. var index = rightGrid.ColumnDefinitions.Count;
  159. RecipeStep recipeStep;
  160. if (copyIndex == -1)
  161. {
  162. recipeStep = new RecipeStep();
  163. recipeStep.StepNo = index + 1;
  164. if(QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.WaferSize").ToString() == "8")
  165. recipeStep.LstUnit = RecipeUnity.GetAllUnits(currentChamber, CurrentRecipe.Header.Type, 8);
  166. else
  167. recipeStep.LstUnit = RecipeUnity.GetAllUnits(currentChamber, CurrentRecipe.Header.Type);
  168. CurrentRecipe.Steps.Add(recipeStep);
  169. }
  170. else
  171. {
  172. var t = JsonConvert.SerializeObject(CurrentRecipe);
  173. recipeStep = Recipe.Load(t).Steps[copyIndex - 1];
  174. recipeStep.StepNo = index + 1;
  175. CurrentRecipe.Steps.Add(recipeStep);
  176. }
  177. ColumnDefinition col1 = new ColumnDefinition();
  178. col1.Width = GridLength.Auto;
  179. rightGrid.ColumnDefinitions.Insert(index, col1);
  180. RecipeStepToGridColumn(recipeStep, rightGrid, index);
  181. }
  182. }
  183. private void OnDeleteStep()
  184. {
  185. if (CurrentRecipe != null)
  186. {
  187. OnDeleteStep(CurrentRecipe.Steps.Count - 1);
  188. }
  189. }
  190. private void OnSaveRecipe()
  191. {
  192. if (WPFMessageBox.ShowQuestion($"Save recipe file?", "") == MessageBoxResult.Yes)
  193. {
  194. var inUseRecipe = QueryDataClient.Instance.Service.GetData($"Scheduler.InUsingRecipe");
  195. if (inUseRecipe != null)
  196. {
  197. if ((inUseRecipe as List<string>).Contains($"{ModuleName}.{CurrentRecipe.Header.Type}.{CurrentRecipeName}"))
  198. {
  199. WPFMessageBox.ShowError($"{CurrentRecipeName} Recipe is In Use,can not edit");
  200. return;
  201. }
  202. }
  203. }
  204. CurrentRecipe.Header.EditTime = DateTime.Now.ToString();
  205. //SaveRecipe(CurrentRecipeName, RecipeUnity.RecipeToString(CurrentRecipe));
  206. var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, typeFolder, CurrentRecipeName + ".rcp");
  207. FileInfo fi = new FileInfo(newrecipePath);
  208. var di = fi.Directory;
  209. if (!di.Exists)
  210. {
  211. di.Create();
  212. }
  213. //File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(CurrentRecipe),Encoding.UTF8);
  214. string recipeContent = RecipeUnity.RecipeToString(CurrentRecipe);
  215. for (int index = 0; index < CurrentRecipe.Steps.Count; index++)
  216. {
  217. if (CurrentRecipe.Steps[index].Type == StepType.OverEtch)
  218. {
  219. if (index == 0)
  220. {
  221. WPFMessageBox.ShowError($"{CurrentRecipeName} Recipe has first item type is OverEtch");
  222. return;
  223. }
  224. if (CurrentRecipe.Steps[index - 1].Type != StepType.EndPoint)
  225. {
  226. WPFMessageBox.ShowError($"{CurrentRecipeName} Recipe contains steps not EndPoint before OverEtch");
  227. return;
  228. }
  229. }
  230. }
  231. SaveRecipe(CurrentRecipe.Header.Name, CurrentRecipe.Header.Type.ToString(), recipeContent);
  232. //LoadHeadWrapPanel(headWrapPanel, CurrentRecipe);
  233. SaveEAPRecipe(recipeContent, CurrentRecipe.Steps);
  234. }
  235. private void SaveEAPRecipe(string recipeContent, ObservableCollection<RecipeStep> Steps)
  236. {
  237. if (currentChamber == JetChamber.Kepler2200A || currentChamber == JetChamber.Kepler2200B)
  238. {
  239. var newrecipePath2 = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, $"{typeFolder}_EAP", CurrentRecipeName + ".rcp");
  240. FileInfo fi2 = new FileInfo(newrecipePath2);
  241. var di2 = fi2.Directory;
  242. if (!di2.Exists)
  243. {
  244. di2.Create();
  245. }
  246. var newContent = Recipe.ShowEAPRecipe(recipeContent, CurrentRecipe.Steps);
  247. File.WriteAllText(newrecipePath2, newContent, Encoding.UTF8);
  248. }
  249. }
  250. private void OnSaveToRecipe(object obj)
  251. {
  252. if (CurrentRecipe == null)
  253. {
  254. return;
  255. }
  256. string moduleName = "";
  257. switch (obj.ToString())
  258. {
  259. case "0":
  260. moduleName = "PMA";
  261. break;
  262. case "1":
  263. moduleName = "PMB";
  264. break;
  265. case "2":
  266. moduleName = "PMC";
  267. break;
  268. case "3":
  269. moduleName = "PMD";
  270. break;
  271. case "4":
  272. moduleName = "ALL";
  273. break;
  274. }
  275. if (moduleName == "")
  276. {
  277. return;
  278. }
  279. if (moduleName == "ALL")
  280. {
  281. var newName = Interaction.InputBox(" ", $"Save Recipe To All", CurrentRecipeName, -1, -1);
  282. OnSaveRecipe();
  283. foreach (var x in moduleList)
  284. {
  285. if (newName != "")
  286. {
  287. var targetChamber = (JetChamber)Enum.Parse(typeof(JetChamber), QueryDataClient.Instance.Service.GetConfig($"{x}.ChamberType").ToString());
  288. if (currentChamber != targetChamber || x == ModuleName)
  289. {
  290. continue;
  291. }
  292. var newRecipe = CurrentRecipe;
  293. newRecipe.Header.Name = newName;
  294. newRecipe.Header.CreateTime = DateTime.Now.ToString();
  295. var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", x, typeFolder, newName + ".rcp");
  296. FileInfo fi = new FileInfo(newrecipePath);
  297. var di = fi.Directory;
  298. if (!di.Exists)
  299. {
  300. di.Create();
  301. }
  302. //File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
  303. if (m_uiRecipeManager.SaveAsRecipeWithType(x, CurrentRecipe.Header.Type.ToString(), newName, RecipeUnity.RecipeToString(newRecipe)))
  304. {
  305. UpdateRecipeFileList();
  306. }
  307. UpdateRecipeFileList();
  308. }
  309. }
  310. }
  311. else
  312. {
  313. var targetChamber = (JetChamber)Enum.Parse(typeof(JetChamber), QueryDataClient.Instance.Service.GetConfig($"{moduleName}.ChamberType").ToString());
  314. if (currentChamber != targetChamber)
  315. {
  316. WPFMessageBox.ShowError($"Recipe can not from {currentChamber.ToString()} copy to {targetChamber.ToString()}");
  317. return;
  318. }
  319. var newName = Interaction.InputBox(" ", $"Save Recipe To {moduleName}", CurrentRecipeName, -1, -1);
  320. if (newName != "")
  321. {
  322. OnSaveRecipe();
  323. var newRecipe = CurrentRecipe;
  324. newRecipe.Header.Name = newName;
  325. newRecipe.Header.CreateTime = DateTime.Now.ToString();
  326. var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", moduleName, typeFolder, newName + ".rcp");
  327. FileInfo fi = new FileInfo(newrecipePath);
  328. var di = fi.Directory;
  329. if (!di.Exists)
  330. {
  331. di.Create();
  332. }
  333. //File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
  334. if (m_uiRecipeManager.SaveAsRecipeWithType(moduleName, CurrentRecipe.Header.Type.ToString(), newName, RecipeUnity.RecipeToString(newRecipe)))
  335. {
  336. UpdateRecipeFileList();
  337. }
  338. //if (SaveAsRecipeWithType(newName, CurrentRecipe.Header.Type.ToString(), RecipeUnity.RecipeToString(newRecipe)))
  339. //{
  340. //}
  341. }
  342. }
  343. }
  344. private async void OnLoaded(Object myrecipeView)
  345. {
  346. if (firstLoad == true)
  347. {
  348. currentChamber = (JetChamber)Enum.Parse(typeof(JetChamber), QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.ChamberType").ToString());
  349. if (currentChamber != JetChamber.Kepler2200A && currentChamber != JetChamber.Kepler2200B)
  350. {
  351. isInstalledEPD = bool.Parse(QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.EPD.IsEnabled").ToString());
  352. }
  353. firstLoad = false;
  354. recipeView = myrecipeView as RecipeView;
  355. treeViewRcpList = recipeView.treeViewRcpList;
  356. headWrapPanel = recipeView.headWrapPanel;
  357. //bodyStackPanel = recipeView.bodyStackPanel;
  358. leftGrid = recipeView.leftGrid;
  359. rightGrid = recipeView.rightGrid;
  360. UpdateRecipeFileList();
  361. treeViewRcpList.SelectedItemChanged += TreeViewRcpList_SelectedItemChanged;
  362. string allModules = QueryDataClient.Instance.Service.GetConfig($"System.InstalledModules").ToString();
  363. if (allModules.Contains("PMA"))
  364. {
  365. PMAIsInstalled = true;
  366. moduleList.Add("PMA");
  367. }
  368. if (allModules.Contains("PMB"))
  369. {
  370. PMBIsInstalled = true;
  371. moduleList.Add("PMB");
  372. }
  373. if (allModules.Contains("PMC"))
  374. {
  375. PMCIsInstalled = true;
  376. moduleList.Add("PMC");
  377. }
  378. if (allModules.Contains("PMD"))
  379. {
  380. PMDIsInstalled = true;
  381. moduleList.Add("PMD");
  382. }
  383. }
  384. if (isInstalledEPD)
  385. {
  386. for (int i = 0; i < 5; i++)
  387. {
  388. InvokeClient.Instance.Service.DoOperation($"{ModuleName}.EndPoint.SearchCfg");
  389. await Task.Delay(200);
  390. currentEPDType = (EPDType)System.Convert.ToInt32(QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.EPD.EPDType"));
  391. if (currentEPDType == EPDType.Socket)
  392. {
  393. EPDCfgList = (List<string>)QueryDataClient.Instance.Service.GetData($"{ModuleName}.EPDCfgList");
  394. }
  395. if (EPDCfgList != null)
  396. {
  397. EPDCfgList.Add("");
  398. break;
  399. }
  400. }
  401. }
  402. UpdateRecipeFileList();
  403. }
  404. private void TreeViewRcpList_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
  405. {
  406. //rightGrid.Visibility = Visibility.Visible;
  407. selectedItem = e.NewValue as TreeViewFileItem;
  408. if (selectedItem == null)
  409. return;
  410. try
  411. {
  412. string[] info = selectedItem.FileName.Split('\\');
  413. //string path;
  414. string xmlRecipeData = "";
  415. if (info.Length == 1)
  416. {
  417. CurrentRecipeName = info[0];
  418. typeFolder = "";
  419. string path = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, $"{CurrentRecipeName}.rcp");
  420. xmlRecipeData = m_uiRecipeManager.LoadRecipeByPath(path);
  421. }
  422. else if (info.Length == 2)
  423. {
  424. string type = info[0];
  425. typeFolder = type;
  426. CurrentRecipeName = info[1];
  427. string path = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, type, $"{CurrentRecipeName}.rcp");
  428. xmlRecipeData = m_uiRecipeManager.LoadRecipeByPath(path);
  429. }
  430. else
  431. {
  432. return;
  433. }
  434. if (xmlRecipeData == "")
  435. {
  436. treeViewRcpList.Items.Remove(selectedItem);
  437. return;
  438. }
  439. CurrentRecipe = Recipe.Load(xmlRecipeData);
  440. if (CurrentRecipe.Header.ChamberType != currentChamber)
  441. {
  442. WPFMessageBox.ShowError($"Can not Open {CurrentRecipe.Header.ChamberType} Recipe in {currentChamber} Chamber,please delete it.");
  443. return;
  444. }
  445. LoadHeadWrapPanel(headWrapPanel, CurrentRecipe);
  446. LoadRecipe(CurrentRecipe);
  447. }
  448. catch (Exception ex)
  449. {
  450. MessageBox.Show(string.Format(Application.Current.Resources["GlobalLableTitleRecipeEditor"].ToString(), ex.Message), Application.Current.Resources["GlobalLableTitleRecipeEditor"].ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
  451. }
  452. e.Handled = true;
  453. }
  454. public bool SaveRecipe(string recipeName, string type, string recipeContent)
  455. {
  456. return m_uiRecipeManager.SaveRecipeWithType(ModuleName, type, recipeName, recipeContent);
  457. }
  458. private void OnMouseRightButtonDown(Object treeView)
  459. {
  460. //treeViewRcpList = treeView as TreeView;
  461. treeViewRcpList.ContextMenu = new ContextMenu() { Background = new SolidColorBrush(Colors.AliceBlue) };
  462. MenuItem menuItem = new MenuItem();
  463. menuItem = new MenuItem();
  464. menuItem.Tag = "\\";
  465. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_CreateRecipe);
  466. menuItem.Header = "New Recipe";
  467. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  468. menuItem = new MenuItem();
  469. menuItem.Tag = "\\";
  470. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_DeleteRecipe);
  471. menuItem.Header = "Delete Recipe";
  472. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  473. menuItem = new MenuItem();
  474. menuItem.Tag = "\\";
  475. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_SaveAsRecipe);
  476. menuItem.Header = "Save As Recipe";
  477. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  478. menuItem = new MenuItem();
  479. menuItem.Tag = "\\";
  480. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_RenameRecipe);
  481. menuItem.Header = "Rename";
  482. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  483. treeViewRcpList.ContextMenu.Visibility = Visibility.Visible;
  484. }
  485. private void OnMouseLeftButtonDown(Object treeView)
  486. {
  487. //treeViewRcpList = treeView as TreeView;
  488. }
  489. private void menuItem_MouseClick_CreateRecipe(object sender, RoutedEventArgs e)
  490. {
  491. MenuItem mit = sender as MenuItem;
  492. string folderName = mit.Tag as string;
  493. PerformCreateRecipe(folderName);
  494. }
  495. private void PerformCreateRecipe(string folderName)
  496. {
  497. try
  498. {
  499. bool hasHV = false;
  500. if (currentChamber == JetChamber.VenusSE || currentChamber == JetChamber.VenusDE)
  501. {
  502. hasHV = true;
  503. }
  504. //RecipeNameInputDlg dlg = new RecipeNameInputDlg(Application.Current.Resources["GlobalLableMsgInputRecipeName"].ToString(), hasHV)
  505. RecipeNameInputDlg dlg = new RecipeNameInputDlg("Input Recipe Name", hasHV)
  506. {
  507. Owner = Application.Current.MainWindow
  508. };
  509. if (dlg.ShowDialog() == true)
  510. {
  511. var recipeName = dlg.InputText;
  512. //var recipeName = folderName + dlg.InputText;
  513. //var recipeName = folderName + "\\" + dlg.InputText;
  514. if (!RecipeNameIsOk(recipeName))
  515. {
  516. return;
  517. }
  518. RecipeType type = (RecipeType)Enum.Parse(typeof(RecipeType), dlg.SelectedType);
  519. //string newRecipe = RecipeUnity.CreateRecipe(currentChamber, type, dlg.InputText);
  520. string newRecipe = RecipeUnity.CreateRecipe(currentChamber, type, dlg.InputText, GlobalUser.Instance.User.Name);
  521. if (QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.WaferSize").ToString() == "8")
  522. newRecipe = RecipeUnity.CreateRecipe(currentChamber, type, dlg.InputText, GlobalUser.Instance.User.Name, 8);
  523. else
  524. newRecipe = RecipeUnity.CreateRecipe(currentChamber, type, dlg.InputText, GlobalUser.Instance.User.Name);
  525. if (SaveAsRecipeWithType(recipeName, type.ToString(), newRecipe))
  526. {
  527. UpdateRecipeFileList();
  528. }
  529. }
  530. }
  531. catch (Exception ex)
  532. {
  533. LOG.WriteExeption(ex);
  534. MessageBox.Show(string.Format(Application.Current.Resources["GlobalLableMsgRecipeCreateException"].ToString(), ex.Message), Application.Current.Resources["GlobalLableTitleRecipeEditor"].ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
  535. }
  536. }
  537. private void menuItem_MouseClick_DeleteRecipe(object sender, RoutedEventArgs e)
  538. {
  539. //if (CurrentRecipe == null)
  540. //{
  541. // return;
  542. //}
  543. if (WPFMessageBox.ShowQuestion($"Delete {typeFolder}Recipe {CurrentRecipeName}?", "删除后无法恢复!!!") == MessageBoxResult.Yes)
  544. {
  545. MenuItem mit = sender as MenuItem;
  546. //string recipename = mit.Header.ToString();
  547. string path = typeFolder == "" ? CurrentRecipeName : $"{typeFolder}\\{CurrentRecipeName}";
  548. m_uiRecipeManager.DeleteRecipe(ModuleName, path);
  549. //PerformCreateRecipe(folderName);
  550. //treeViewRcpList.Items.Remove(selectedItem);
  551. UpdateRecipeFileList();
  552. }
  553. }
  554. private void menuItem_MouseClick_SaveAsRecipe(object sender, RoutedEventArgs e)
  555. {
  556. if (CurrentRecipe == null)
  557. {
  558. return;
  559. }
  560. var newName = Interaction.InputBox(" ", "Save As Recipe", CurrentRecipeName, -1, -1);
  561. if (!RecipeNameIsOk(newName))
  562. {
  563. return;
  564. }
  565. //newName = newName.Trim();
  566. if (newName != CurrentRecipeName && newName != "")
  567. {
  568. var newRecipe = CurrentRecipe;
  569. if (WPFMessageBox.ShowQuestion($"Save recipe file {newName} ?", "") == MessageBoxResult.Yes)
  570. {
  571. //MessageBox.Show($"Save as recipe {newName} ?", "Save As Recipe", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
  572. newRecipe.Header.Name = newName;
  573. newRecipe.Header.CreateTime = DateTime.Now.ToString();
  574. //var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, typeFolder, newName + ".rcp");
  575. //File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
  576. if (SaveAsRecipeWithType(newName, CurrentRecipe.Header.Type.ToString(), RecipeUnity.RecipeToString(newRecipe)))
  577. {
  578. UpdateRecipeFileList();
  579. CurrentRecipeName = newName;
  580. //LoadHeadWrapPanel(headWrapPanel, CurrentRecipe);
  581. LoadRecipe(CurrentRecipe);
  582. }
  583. }
  584. }
  585. else if (newName == CurrentRecipeName || newName == "")
  586. {
  587. WPFMessageBox.Show("Please input right recipename", MessageBoxButton.OK);
  588. }
  589. }
  590. private void menuItem_MouseClick_RenameRecipe(object sender, RoutedEventArgs e)
  591. {
  592. if (CurrentRecipe == null)
  593. {
  594. return;
  595. }
  596. var newName = Interaction.InputBox(" ", "Rename Recipe", CurrentRecipeName, -1, -1);
  597. //newName = newName.Trim();
  598. if (!RecipeNameIsOk(newName))
  599. {
  600. return;
  601. }
  602. if (newName != CurrentRecipeName && newName != "")
  603. {
  604. var newRecipe = CurrentRecipe;
  605. if (WPFMessageBox.ShowQuestion($"Save recipe file {newName} ?", "") == MessageBoxResult.Yes)
  606. {
  607. newRecipe.Header.Name = newName;
  608. newRecipe.Header.CreateTime = DateTime.Now.ToString();
  609. var oldrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, typeFolder, CurrentRecipeName + ".rcp");
  610. var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, typeFolder, newName + ".rcp");
  611. File.Delete(oldrecipePath);
  612. File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
  613. UpdateRecipeFileList();
  614. }
  615. }
  616. else if (newName == CurrentRecipeName || newName == "")
  617. {
  618. WPFMessageBox.Show("Please input right recipename", MessageBoxButton.OK);
  619. }
  620. }
  621. public bool SaveAsRecipeWithType(string recipeName, string type, string recipeContent)
  622. {
  623. return m_uiRecipeManager.SaveAsRecipeWithType(ModuleName, type, recipeName, recipeContent);
  624. }
  625. public string GetXmlRecipeList()
  626. {
  627. return m_uiRecipeManager.GetXmlRecipeList(ModuleName, true) ?? "";
  628. }
  629. void CreateTreeViewItems(XmlElement curElementNode, ItemsControl itemsControl)
  630. {
  631. foreach (XmlElement ele in curElementNode.ChildNodes)
  632. {
  633. if (ele.Name == "File")
  634. {
  635. string fileName = ele.Attributes["Name"].Value;
  636. fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
  637. TreeViewFileItem item = new TreeViewFileItem(ele.Attributes["Name"].Value);
  638. item.Tag = ele.Attributes["Name"].Value;
  639. if (!item.Tag.ToString().Contains("\\"))
  640. {
  641. continue;
  642. }
  643. itemsControl.Items.Add(item);
  644. }
  645. else if (ele.Name == "Folder")
  646. {
  647. string folderName = ele.Attributes["Name"].Value;
  648. folderName = folderName.Substring(folderName.LastIndexOf('\\') + 1);
  649. if (folderName == Venus_Core.RecipeType.Process.ToString() || folderName == Venus_Core.RecipeType.Clean.ToString() || folderName == Venus_Core.RecipeType.Chuck.ToString() || folderName == Venus_Core.RecipeType.DeChuck.ToString())
  650. {
  651. TreeViewFolderItem item = new TreeViewFolderItem(folderName);
  652. item.Tag = ele.Attributes["Name"].Value;
  653. CreateTreeViewItems(ele, item);
  654. item.IsExpanded = false;
  655. itemsControl.Items.Add(item);
  656. }
  657. }
  658. }
  659. }
  660. private IEnumerable<string> GetFilesNames(string path)
  661. {
  662. if (Directory.Exists(path))
  663. {
  664. return Directory.GetFiles(path, "*.rcp")?
  665. .Select(Path.GetFileNameWithoutExtension);
  666. }
  667. else
  668. {
  669. return new List<string>();
  670. }
  671. }
  672. private void LoadHeadWrapPanel(WrapPanel HeadWrapPanel, Recipe recipe)
  673. {
  674. HeadWrapPanel.Children.Clear();
  675. Type type = recipe.Header.GetType();
  676. foreach (var propertyInfo in type.GetProperties())
  677. {
  678. TextBlock textBlock = new TextBlock();
  679. textBlock.FontSize = 16;
  680. textBlock.Margin = new Thickness(0, 20, 0, 0);
  681. textBlock.Width = 200;
  682. if ((currentChamber != JetChamber.VenusDE && currentChamber != JetChamber.VenusSE) && propertyInfo.Name == "WallTemperature")
  683. {
  684. continue;
  685. }
  686. if ((currentChamber == JetChamber.VenusDE || currentChamber == JetChamber.VenusSE) && propertyInfo.Name == "Barcode")
  687. {
  688. continue;
  689. }
  690. switch (propertyInfo.Name)
  691. {
  692. case "ChuckRecipe":
  693. if (currentChamber != JetChamber.VenusSE && currentChamber != JetChamber.VenusDE)
  694. {
  695. continue;
  696. }
  697. textBlock.Text = "Chuck:";
  698. break;
  699. case "DechuckRecipe":
  700. if (currentChamber != JetChamber.VenusSE && currentChamber != JetChamber.VenusDE)
  701. {
  702. continue;
  703. }
  704. textBlock.Text = "DeChuck:";
  705. break;
  706. default:
  707. object[] NameAttrs = propertyInfo.GetCustomAttributes(typeof(CustomName), true);
  708. string name;
  709. if (NameAttrs.Length > 0)
  710. {
  711. name = (NameAttrs[0] as CustomName).Name;
  712. }
  713. else
  714. {
  715. name = propertyInfo.Name;
  716. }
  717. textBlock.Text = name + ":";
  718. break;
  719. }
  720. textBlock.Margin = new Thickness(15, 0, 0, 0);
  721. textBlock.VerticalAlignment = VerticalAlignment.Center;
  722. HeadWrapPanel.Children.Add(textBlock);
  723. Binding binding = new Binding()
  724. {
  725. Source = recipe.Header, // 数据源
  726. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  727. Mode = BindingMode.TwoWay, // 绑定模式
  728. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, //触发器
  729. };
  730. var propertyTypeName = propertyInfo.PropertyType.Name;
  731. var propertyInfoName = propertyInfo.Name;
  732. Control control = new Control();
  733. switch (propertyInfoName)
  734. {
  735. case "ChamberType":
  736. control = new ComboBox();
  737. control.IsEnabled = false;
  738. //control.Height = 23;
  739. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  740. control.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  741. ItemsControlHelper.SetEnumValuesToItemsSource(control, true);
  742. break;
  743. case "Type":
  744. ComboBox cb = new ComboBox();
  745. cb.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  746. cb.IsEnabled = false;
  747. cb.SelectionChanged += ChangeUI;
  748. control = cb;
  749. //control.Height = 23;
  750. ItemsControlHelper.SetEnumValuesToItemsSource(control, true);
  751. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  752. break;
  753. case "ChuckRecipe":
  754. StringBuilder stringBuilder = new StringBuilder();
  755. control = new ComboBox()
  756. {
  757. ItemsSource = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\Chuck"))
  758. };
  759. //control.Height = 23;
  760. control.MinWidth = 100;
  761. control.MaxWidth = 300;
  762. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  763. control.PreviewMouseLeftButtonDown += ChuckControl_PreviewMouseLeftButtonDown;
  764. break;
  765. case "DechuckRecipe":
  766. //if (currentChamber != JetChamber.Venus)
  767. //{
  768. // continue;
  769. //}
  770. //string[] dechucklist = new string[] { "" };
  771. //ArrayList dearrayList = new ArrayList(dechucklist.ToList());
  772. //IEnumerable<string> delist = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList().Where(item => item.ToLower().Contains("dechuck"));
  773. //foreach (var i in delist)
  774. //{
  775. // dearrayList.Add(i);
  776. //}
  777. //dechucklist = (string[])dearrayList.ToArray(typeof(string));
  778. //StringBuilder destringBuilder = new StringBuilder();
  779. //for (int i = 0; i < dechucklist.Length; i++)
  780. //{
  781. // destringBuilder.Append(dechucklist[i] + "\t");
  782. //}
  783. control = new ComboBox()
  784. {
  785. ItemsSource = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\DeChuck"))
  786. };
  787. //control.Height = 23;
  788. control.MinWidth = 100;
  789. control.MaxWidth = 300;
  790. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  791. control.PreviewMouseLeftButtonDown += DechuckControl_PreviewMouseLeftButtonDown;
  792. break;
  793. case "IsShowTolerance":
  794. control = new CheckBox();
  795. control.SetBinding(CheckBox.IsCheckedProperty, binding);
  796. control.Style = null;
  797. control.VerticalAlignment = VerticalAlignment.Center;
  798. (control as CheckBox).Checked += RecipeViewModel_Checked;
  799. (control as CheckBox).Unchecked += RecipeViewModel_Checked;
  800. break;
  801. default:
  802. control = new TextBox();
  803. control.Margin = new Thickness(1, 0, 0, 0);
  804. control.BorderThickness = new Thickness(0, 0, 0, 1);
  805. control.BorderBrush = Brushes.White;
  806. control.FontSize = 15;
  807. control.Foreground = Brushes.Green;
  808. control.Background = Brushes.Transparent;
  809. control.VerticalAlignment = VerticalAlignment.Center;
  810. control.MinWidth = 15;
  811. control.SetBinding(TextBox.TextProperty, binding);
  812. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  813. if (objAttrs.Length > 0)
  814. {
  815. (control as TextBox).IsReadOnly = true;
  816. }
  817. break;
  818. }
  819. control.Margin = new Thickness(20, 3, 0, 7);
  820. control.Width = 250;
  821. HeadWrapPanel.Children.Add(control);
  822. }
  823. }
  824. private void RecipeViewModel_Checked(object sender, RoutedEventArgs e)
  825. {
  826. LoadRecipe(CurrentRecipe);
  827. }
  828. private void ChuckControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  829. {
  830. var items = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\Chuck")).ToList();
  831. items.Add("");
  832. (sender as ComboBox).ItemsSource = items;
  833. }
  834. private void DechuckControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  835. {
  836. var items = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\DeChuck")).ToList();
  837. items.Add("");
  838. (sender as ComboBox).ItemsSource = items;
  839. }
  840. private void ChangeUI(object sender, SelectionChangedEventArgs e)
  841. {
  842. var t = sender as ComboBox;
  843. if (t.SelectedValue.ToString() != "Process")
  844. {
  845. headWrapPanel.Children[8].Visibility = Visibility.Collapsed;
  846. headWrapPanel.Children[9].Visibility = Visibility.Collapsed;
  847. headWrapPanel.Children[10].Visibility = Visibility.Collapsed;
  848. headWrapPanel.Children[11].Visibility = Visibility.Collapsed;
  849. }
  850. else
  851. {
  852. headWrapPanel.Children[8].Visibility = Visibility.Visible;
  853. headWrapPanel.Children[9].Visibility = Visibility.Visible;
  854. headWrapPanel.Children[10].Visibility = Visibility.Visible;
  855. headWrapPanel.Children[11].Visibility = Visibility.Visible;
  856. }
  857. }
  858. private void MenuItemLeftInsert_Click(object sender, RoutedEventArgs e)
  859. {
  860. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  861. int insertIndex = Convert.ToInt32(t.Text) - 1;
  862. RecipeStep recipeStep;
  863. if (copyIndex == -1)
  864. {
  865. recipeStep = new RecipeStep();
  866. if (QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.WaferSize").ToString() == "8")
  867. recipeStep.LstUnit = RecipeUnity.GetAllUnits(currentChamber, CurrentRecipe.Header.Type, 8);
  868. else
  869. recipeStep.LstUnit = RecipeUnity.GetAllUnits(currentChamber, CurrentRecipe.Header.Type);
  870. CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
  871. }
  872. else
  873. {
  874. var t1 = JsonConvert.SerializeObject(CurrentRecipe);
  875. recipeStep = Recipe.Load(t1).Steps[copyIndex - 1];
  876. CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
  877. }
  878. for (int i = 0; i < CurrentRecipe.Steps.Count; i++)
  879. {
  880. CurrentRecipe.Steps[i].StepNo = i + 1;
  881. }
  882. ColumnDefinition col1 = new ColumnDefinition();
  883. col1.Width = GridLength.Auto;
  884. rightGrid.ColumnDefinitions.Add(col1);
  885. for (int i = 0; i < rightGrid.Children.Count; i++)
  886. {
  887. if (Grid.GetColumn(rightGrid.Children[i]) >= insertIndex)
  888. {
  889. Grid.SetColumn(rightGrid.Children[i], Grid.GetColumn(rightGrid.Children[i]) + 1);
  890. }
  891. }
  892. RecipeStepToGridColumn(recipeStep, rightGrid, insertIndex);
  893. }
  894. private void MenuItemRightInsert_Click(object sender, RoutedEventArgs e)
  895. {
  896. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  897. int insertIndex = Convert.ToInt32(t.Text);
  898. RecipeStep recipeStep;
  899. if (copyIndex == -1)
  900. {
  901. recipeStep = new RecipeStep();
  902. if (QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.WaferSize").ToString() == "8")
  903. recipeStep.LstUnit = RecipeUnity.GetAllUnits(currentChamber, CurrentRecipe.Header.Type, 8);
  904. else
  905. recipeStep.LstUnit = RecipeUnity.GetAllUnits(currentChamber, CurrentRecipe.Header.Type);
  906. CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
  907. }
  908. else
  909. {
  910. var t1 = JsonConvert.SerializeObject(CurrentRecipe);
  911. recipeStep = Recipe.Load(t1).Steps[copyIndex - 1];
  912. CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
  913. }
  914. for (int i = 0; i < CurrentRecipe.Steps.Count; i++)
  915. {
  916. CurrentRecipe.Steps[i].StepNo = i + 1;
  917. }
  918. ColumnDefinition col1 = new ColumnDefinition();
  919. col1.Width = GridLength.Auto;
  920. rightGrid.ColumnDefinitions.Add(col1);
  921. for (int i = 0; i < rightGrid.Children.Count; i++)
  922. {
  923. if (Grid.GetColumn(rightGrid.Children[i]) >= insertIndex)
  924. {
  925. Grid.SetColumn(rightGrid.Children[i], Grid.GetColumn(rightGrid.Children[i]) + 1);
  926. }
  927. }
  928. RecipeStepToGridColumn(recipeStep, rightGrid, insertIndex);
  929. }
  930. private void MenuItemDelete_Click(object sender, RoutedEventArgs e)
  931. {
  932. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  933. int deleteIndex = Convert.ToInt32(t.Text) - 1;
  934. CurrentRecipe.Steps.RemoveAt(deleteIndex);
  935. for (int i = 0; i < CurrentRecipe.Steps.Count; i++)
  936. {
  937. CurrentRecipe.Steps[i].StepNo = i + 1;
  938. }
  939. RemoveColumnFromGrid(rightGrid, deleteIndex);
  940. rightGrid.ColumnDefinitions.RemoveAt(deleteIndex);
  941. for (int i = 0; i < rightGrid.Children.Count; i++)
  942. {
  943. if (Grid.GetColumn(rightGrid.Children[i]) >= deleteIndex)
  944. {
  945. Grid.SetColumn(rightGrid.Children[i], Grid.GetColumn(rightGrid.Children[i]) - 1);
  946. }
  947. }
  948. }
  949. private void MenuItemCopy_Click(object sender, RoutedEventArgs e)
  950. {
  951. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  952. copyIndex = Convert.ToInt32(t.Text);
  953. }
  954. #endregion
  955. #region 私有方法
  956. private void RecipeStepToGridColumn(RecipeStep recipeStep, Grid grid, int columnIndex)
  957. {
  958. Type recipeType = recipeStep.GetType();
  959. int rowIndex = 0;
  960. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  961. {
  962. string propertyInfoName = propertyInfo.Name;
  963. string propertyTypeName = propertyInfo.PropertyType.Name;
  964. if (propertyInfoName != "LstUnit")
  965. {
  966. if ((propertyInfoName == "EPDConfig" || propertyInfoName == "MinEndPointTime" || propertyInfoName == "MaxEndPointTime" || propertyInfoName == "OverEtchPercent") && isInstalledEPD == false)
  967. {
  968. continue;
  969. }
  970. if (columnIndex == 0)
  971. {
  972. RowDefinition row1 = new RowDefinition();
  973. row1.Height = new GridLength(controlHeight);
  974. grid.RowDefinitions.Add(row1);
  975. }
  976. Binding binding = new Binding()
  977. {
  978. Source = recipeStep, // 数据源
  979. Path = new PropertyPath(propertyInfoName), // 需绑定的数据源属性名
  980. Mode = BindingMode.TwoWay, // 绑定模式
  981. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  982. };
  983. switch (propertyTypeName)
  984. {
  985. case "Int32":
  986. case "String":
  987. case "Single":
  988. case "Double":
  989. if (propertyInfoName == "EPDConfig")
  990. {
  991. if (currentEPDType == EPDType.Socket)
  992. {
  993. ComboBox EPDcomboBox = new ComboBox();
  994. EPDcomboBox.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  995. EPDcomboBox.Background = new SolidColorBrush(Colors.Black);
  996. EPDcomboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  997. EPDcomboBox.ItemsSource = EPDCfgList;
  998. grid.Children.Add(EPDcomboBox);
  999. Grid.SetRow(EPDcomboBox, rowIndex);
  1000. Grid.SetColumn(EPDcomboBox, columnIndex);
  1001. }
  1002. else if (currentEPDType == EPDType.WCF)
  1003. {
  1004. Button EPDButton = new Button();
  1005. EPDButton.Content = "EndPoint";
  1006. EPDButton.Cursor = Cursors.Hand;
  1007. EPDButton.Tag = $"{CurrentRecipeName}.{(columnIndex).ToString()}";
  1008. EPDButton.Style = null;
  1009. EPDButton.Click += EPDButton_Click;
  1010. grid.Children.Add(EPDButton);
  1011. Grid.SetRow(EPDButton, rowIndex);
  1012. Grid.SetColumn(EPDButton, columnIndex);
  1013. }
  1014. break;
  1015. }
  1016. TextBox textBox = new TextBox();
  1017. textBox.HorizontalContentAlignment = HorizontalAlignment.Center;
  1018. textBox.VerticalContentAlignment = VerticalAlignment.Center;
  1019. textBox.SetBinding(TextBox.TextProperty, binding);
  1020. grid.Children.Add(textBox);
  1021. Grid.SetRow(textBox, rowIndex);
  1022. Grid.SetColumn(textBox, columnIndex);
  1023. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  1024. if (objAttrs.Length > 0)
  1025. {
  1026. textBox.IsReadOnly = true;
  1027. ContextMenu contextmenu = new ContextMenu();
  1028. textBox.ContextMenu = contextmenu;
  1029. MenuItem menuItemDelete = new MenuItem();
  1030. menuItemDelete.Header = "Delete";
  1031. menuItemDelete.Click += MenuItemDelete_Click;
  1032. MenuItem menuItemLeftInsert = new MenuItem();
  1033. menuItemLeftInsert.Header = "Left Insert";
  1034. menuItemLeftInsert.Click += MenuItemLeftInsert_Click;
  1035. MenuItem menuItemRightInsert = new MenuItem();
  1036. menuItemRightInsert.Header = "Right Insert";
  1037. menuItemRightInsert.Click += MenuItemRightInsert_Click;
  1038. MenuItem menuItemCopy = new MenuItem();
  1039. menuItemCopy.Tag = textBox.Text;
  1040. menuItemCopy.Header = "Copy";
  1041. menuItemCopy.Click += MenuItemCopy_Click;
  1042. contextmenu.Items.Add(menuItemCopy);
  1043. contextmenu.Items.Add(menuItemDelete);
  1044. contextmenu.Items.Add(menuItemLeftInsert);
  1045. contextmenu.Items.Add(menuItemRightInsert);
  1046. }
  1047. break;
  1048. case "Boolean":
  1049. CheckBox checkBox = new CheckBox();
  1050. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  1051. grid.Children.Add(checkBox);
  1052. Grid.SetRow(checkBox, rowIndex);
  1053. Grid.SetColumn(checkBox, columnIndex);
  1054. break;
  1055. default:
  1056. ComboBox comboBox = new ComboBox();
  1057. comboBox.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  1058. //comboBox.BorderThickness = new Thickness(1, 0, 1, 0);
  1059. comboBox.Background = new SolidColorBrush(Colors.Black);
  1060. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  1061. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  1062. grid.Children.Add(comboBox);
  1063. Grid.SetRow(comboBox, rowIndex);
  1064. Grid.SetColumn(comboBox, columnIndex);
  1065. break;
  1066. }
  1067. rowIndex++;
  1068. }
  1069. }
  1070. int unitIndex = 0;
  1071. foreach (var x in recipeStep.LstUnit.ToList())
  1072. {
  1073. Type unitType = x.GetType();
  1074. Binding checkbinding = null;
  1075. foreach (PropertyInfo propertyInfo in unitType.GetProperties())
  1076. {
  1077. object[] IgnoreAttrs = propertyInfo.GetCustomAttributes(typeof(IsCanConfigIgnore), true);
  1078. bool IsEnableRecipeExtension = Convert.ToBoolean(QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.IsEnableRecipeExtension"));
  1079. if (IgnoreAttrs.Length > 0 && IsEnableRecipeExtension == false)
  1080. {
  1081. break;
  1082. }
  1083. object[] toleranceAttrs = propertyInfo.GetCustomAttributes(typeof(IsTolerance), true);
  1084. if (toleranceAttrs.Length > 0 && CurrentRecipe.Header.IsShowTolerance == false)
  1085. {
  1086. continue;
  1087. }
  1088. if (propertyInfo.Name == "UnitName")
  1089. {
  1090. continue;
  1091. }
  1092. //if (propertyInfo.Name.Contains("Gas"))
  1093. //{
  1094. // if (!(bool)QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.MfcGas1.Enable"))
  1095. // {
  1096. // continue;
  1097. // }
  1098. //}
  1099. if (columnIndex == 0)
  1100. {
  1101. RowDefinition row1 = new RowDefinition();
  1102. row1.Height = new GridLength(controlHeight);
  1103. grid.RowDefinitions.Add(row1);
  1104. }
  1105. Binding binding = new Binding()
  1106. {
  1107. Source = recipeStep.LstUnit[unitIndex], // 数据源
  1108. //Path = new PropertyPath($"LstUnit[{k}]." + propertyInfo.Name), // 需绑定的数据源属性名
  1109. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  1110. Mode = BindingMode.TwoWay, // 绑定模式
  1111. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  1112. };
  1113. var item = propertyInfo.PropertyType.Name;
  1114. switch (item)
  1115. {
  1116. case "Int32":
  1117. case "String":
  1118. case "Single":
  1119. case "Double":
  1120. TextBox textBox = new TextBox();
  1121. textBox.HorizontalContentAlignment = HorizontalAlignment.Center;
  1122. textBox.VerticalContentAlignment = VerticalAlignment.Center;
  1123. if (checkbinding == null)
  1124. {
  1125. textBox.IsEnabled = true;
  1126. }
  1127. else
  1128. {
  1129. textBox.SetBinding(TextBox.IsEnabledProperty, checkbinding);
  1130. }
  1131. textBox.SetBinding(TextBox.TextProperty, binding);
  1132. grid.Children.Add(textBox);
  1133. Grid.SetRow(textBox, rowIndex);
  1134. Grid.SetColumn(textBox, columnIndex);
  1135. //object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  1136. //if (objAttrs.Length > 0)
  1137. //{
  1138. // textBox.IsReadOnly = true;
  1139. //}
  1140. break;
  1141. case "Boolean":
  1142. CheckBox checkBox = new CheckBox();
  1143. if (checkbinding == null)
  1144. {
  1145. checkbinding = new Binding
  1146. {
  1147. Source = checkBox, // 数据源
  1148. Path = new PropertyPath("IsChecked"), // 需绑定的数据源属性名
  1149. Mode = BindingMode.TwoWay, // 绑定模式
  1150. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  1151. };
  1152. }
  1153. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  1154. grid.Children.Add(checkBox);
  1155. Grid.SetRow(checkBox, rowIndex);
  1156. Grid.SetColumn(checkBox, columnIndex);
  1157. break;
  1158. default:
  1159. //if (checkbinding != null)
  1160. //{
  1161. // break;
  1162. //}
  1163. ComboBox comboBox = new ComboBox();
  1164. comboBox.BorderBrush = Brushes.Gray;
  1165. comboBox.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  1166. //comboBox.BorderThickness =new Thickness(1,0,1,0);
  1167. if (checkbinding == null)
  1168. {
  1169. comboBox.IsEnabled = true;
  1170. }
  1171. else
  1172. {
  1173. comboBox.SetBinding(TextBox.IsEnabledProperty, checkbinding);
  1174. }
  1175. comboBox.Background = Brushes.White;
  1176. string path = propertyInfo.Name;
  1177. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  1178. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  1179. grid.Children.Add(comboBox);
  1180. Grid.SetRow(comboBox, rowIndex);
  1181. Grid.SetColumn(comboBox, columnIndex);
  1182. break;
  1183. }
  1184. rowIndex++;
  1185. }
  1186. unitIndex++;
  1187. }
  1188. }
  1189. private void RecipeStepToGridColumnOnlyTitle(RecipeStep recipeStep, Grid grid)
  1190. {
  1191. Type recipeType = recipeStep.GetType();
  1192. int i = 0;
  1193. ColumnDefinition col1 = new ColumnDefinition();
  1194. grid.ColumnDefinitions.Add(col1);
  1195. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  1196. {
  1197. string propertyInfoName = propertyInfo.Name;
  1198. string propertyTypeName = propertyInfo.PropertyType.Name;
  1199. if (propertyInfoName != "LstUnit")
  1200. {
  1201. if ((propertyInfoName == "EPDConfig" || propertyInfoName == "MinEndPointTime" || propertyInfoName == "MaxEndPointTime" || propertyInfoName == "OverEtchPercent") && isInstalledEPD == false)
  1202. {
  1203. continue;
  1204. }
  1205. RowDefinition row1 = new RowDefinition();
  1206. row1.Height = new GridLength(controlHeight);
  1207. grid.RowDefinitions.Add(row1);
  1208. TextBox textBlock = new TextBox();
  1209. textBlock.Padding = new Thickness(0, 3, 0, 0);
  1210. textBlock.IsReadOnly = true;
  1211. object[] NameAttrs = propertyInfo.GetCustomAttributes(typeof(CustomName), true);
  1212. string name;
  1213. if (NameAttrs.Length > 0)
  1214. {
  1215. name = (NameAttrs[0] as CustomName).Name;
  1216. }
  1217. else
  1218. {
  1219. name = propertyInfo.Name;
  1220. }
  1221. textBlock.Text = name;
  1222. //textBlock.FontSize = 15;
  1223. grid.Children.Add(textBlock);
  1224. textBlock.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FAFAFA"));
  1225. Grid.SetRow(textBlock, i);
  1226. Grid.SetColumn(textBlock, 0);
  1227. i++;
  1228. }
  1229. }
  1230. foreach (var x in recipeStep.LstUnit.ToList())
  1231. {
  1232. Type unitType = x.GetType();
  1233. bool isUnitFirstRow = true;
  1234. foreach (PropertyInfo propertyInfo in unitType.GetProperties())
  1235. {
  1236. object[] IgnoreAttrs = propertyInfo.GetCustomAttributes(typeof(IsCanConfigIgnore), true);
  1237. bool IsEnableRecipeExtension = Convert.ToBoolean(QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.IsEnableRecipeExtension"));
  1238. if (IgnoreAttrs.Length > 0 && IsEnableRecipeExtension == false)
  1239. {
  1240. break;
  1241. }
  1242. object[] toleranceAttrs = propertyInfo.GetCustomAttributes(typeof(IsTolerance), true);
  1243. if (toleranceAttrs.Length > 0 && CurrentRecipe.Header.IsShowTolerance == false)
  1244. {
  1245. continue;
  1246. }
  1247. if (propertyInfo.Name == "UnitName")
  1248. {
  1249. continue;
  1250. }
  1251. if (propertyInfo.Name.Contains("Gas"))
  1252. {
  1253. if (!(bool)QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.MfcGas1.Enable"))
  1254. {
  1255. continue;
  1256. }
  1257. }
  1258. RowDefinition row1 = new RowDefinition();
  1259. row1.Height = new GridLength(controlHeight);
  1260. grid.RowDefinitions.Add(row1);
  1261. TextBox textBlock = new TextBox();
  1262. if (isUnitFirstRow)
  1263. {
  1264. textBlock.FontWeight = FontWeights.Bold;
  1265. textBlock.FontSize = 15;
  1266. isUnitFirstRow = false;
  1267. textBlock.Padding = new Thickness(0, 2, 0, 0);
  1268. }
  1269. else
  1270. {
  1271. textBlock.Padding = new Thickness(0, 3, 0, 0);
  1272. }
  1273. textBlock.IsReadOnly = true;
  1274. switch (propertyInfo.Name)
  1275. {
  1276. case "Gas1":
  1277. var data1 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas1");
  1278. textBlock.Text = $"{propertyInfo.Name}({data1.DisplayName},{data1.Scale})";
  1279. break;
  1280. case "Gas2":
  1281. var data2 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas2");
  1282. textBlock.Text = $"{propertyInfo.Name}({data2.DisplayName},{data2.Scale})";
  1283. break;
  1284. case "Gas3":
  1285. var data3 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas3");
  1286. textBlock.Text = $"{propertyInfo.Name}({data3.DisplayName},{data3.Scale})";
  1287. break;
  1288. case "Gas4":
  1289. var data4 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas4");
  1290. textBlock.Text = $"{propertyInfo.Name}({data4.DisplayName},{data4.Scale})";
  1291. break;
  1292. case "Gas5":
  1293. var data5 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas5");
  1294. textBlock.Text = $"{propertyInfo.Name}({data5.DisplayName},{data5.Scale})";
  1295. break;
  1296. case "Gas6":
  1297. var data6 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas6");
  1298. textBlock.Text = $"{propertyInfo.Name}({data6.DisplayName},{data6.Scale})";
  1299. break;
  1300. case "Gas7":
  1301. var data7 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas7");
  1302. textBlock.Text = $"{propertyInfo.Name}({data7.DisplayName},{data7.Scale})";
  1303. break;
  1304. case "Gas8":
  1305. var data8 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas8");
  1306. textBlock.Text = $"{propertyInfo.Name}({data8.DisplayName},{data8.Scale})";
  1307. break;
  1308. case "Gas9":
  1309. var data9 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas9");
  1310. textBlock.Text = $"{propertyInfo.Name}({data9.DisplayName},{data9.Scale})";
  1311. break;
  1312. case "Gas10":
  1313. var data10 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas10");
  1314. textBlock.Text = $"{propertyInfo.Name}({data10.DisplayName},{data10.Scale})";
  1315. break;
  1316. case "Gas11":
  1317. var data11 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas11");
  1318. textBlock.Text = $"{propertyInfo.Name}({data11.DisplayName},{data11.Scale})";
  1319. break;
  1320. case "Gas12":
  1321. var data12 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas12");
  1322. textBlock.Text = $"{propertyInfo.Name}({data12.DisplayName},{data12.Scale})";
  1323. break;
  1324. default:
  1325. object[] NameAttrs = propertyInfo.GetCustomAttributes(typeof(CustomName), true);
  1326. string name;
  1327. if (NameAttrs.Length > 0)
  1328. {
  1329. name = (NameAttrs[0] as CustomName).Name;
  1330. }
  1331. else
  1332. {
  1333. name = propertyInfo.Name;
  1334. }
  1335. textBlock.Text = name;
  1336. break;
  1337. }
  1338. grid.Children.Add(textBlock);
  1339. Grid.SetRow(textBlock, i);
  1340. Grid.SetColumn(textBlock, 0);
  1341. i++;
  1342. }
  1343. }
  1344. }
  1345. private void EPDButton_Click(object sender, RoutedEventArgs e)
  1346. {
  1347. Button button = sender as Button;
  1348. string para = button.Tag.ToString();
  1349. int stepno = Convert.ToInt32(para.Split('.')[1]) - 1;
  1350. var endpointconfigitem = new MECF.Framework.Common.CommonData.EndPointConfigItem();
  1351. if (CurrentRecipe.Steps[stepno].EPDConfig != null && CurrentRecipe.Steps[stepno].EPDConfig.Length > 20)
  1352. {
  1353. endpointconfigitem.SetValue(CurrentRecipe.Steps[stepno].EPDConfig);
  1354. }
  1355. (new EndPointDlg(para, endpointconfigitem, CurrentRecipe)).ShowDialog();
  1356. }
  1357. private void UpdateRecipeFileList()
  1358. {
  1359. XmlDocument doc = new XmlDocument();
  1360. doc.LoadXml(GetXmlRecipeList());
  1361. treeViewRcpList.Items.Clear();
  1362. CreateTreeViewItems(doc.DocumentElement, this.treeViewRcpList);
  1363. ExpandAllItems(this.treeViewRcpList);
  1364. }
  1365. private void LoadRecipe(Recipe recipe)
  1366. {
  1367. copyIndex = -1;
  1368. OnClearRecipe();
  1369. CurrentRecipe = recipe;
  1370. RecipeStepToGridColumnOnlyTitle(recipe.Steps[0], leftGrid);
  1371. for (int i = 0; i < recipe.Steps.Count; i++)
  1372. {
  1373. ColumnDefinition col1 = new ColumnDefinition();
  1374. col1.Width = GridLength.Auto;
  1375. rightGrid.ColumnDefinitions.Insert(i, col1);
  1376. RecipeStepToGridColumn(recipe.Steps[i], rightGrid, i);
  1377. }
  1378. string recipeContent = RecipeUnity.RecipeToString(CurrentRecipe);
  1379. SaveEAPRecipe(recipeContent, CurrentRecipe.Steps);
  1380. }
  1381. private void OnDeleteStep(int index)
  1382. {
  1383. if (CurrentRecipe != null && CurrentRecipe.Steps.Count > 1)
  1384. {
  1385. RemoveColumnFromGrid(rightGrid, index);
  1386. rightGrid.ColumnDefinitions.RemoveAt(index);
  1387. CurrentRecipe.Steps.RemoveAt(index);
  1388. }
  1389. }
  1390. /// <summary>
  1391. /// 删除Grid某列数据
  1392. /// </summary>
  1393. /// <param name="grid"></param>
  1394. /// <param name="column"></param>
  1395. public void RemoveColumnFromGrid(Grid grid, int column)
  1396. {
  1397. List<UIElement> listControl = new List<UIElement>();
  1398. for (int i = 0; i < grid.Children.Count; i++)
  1399. {
  1400. var child = grid.Children[i];
  1401. if (Grid.GetColumn(child) == column)
  1402. {
  1403. listControl.Add(child);
  1404. }
  1405. }
  1406. listControl.ForEach(x =>
  1407. {
  1408. grid.Children.Remove(x);
  1409. });
  1410. }
  1411. private void OnRefresh()
  1412. {
  1413. if (CurrentRecipeName != "")
  1414. {
  1415. string path = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, typeFolder, $"{CurrentRecipeName}.rcp");
  1416. string xmlRecipeData = m_uiRecipeManager.LoadRecipeByPath(path);
  1417. CurrentRecipe = Recipe.Load(xmlRecipeData);
  1418. LoadHeadWrapPanel(headWrapPanel, CurrentRecipe);
  1419. LoadRecipe(CurrentRecipe);
  1420. }
  1421. }
  1422. private void OnExpand()
  1423. {
  1424. HeadExpand = !HeadExpand;
  1425. if (HeadExpand)
  1426. {
  1427. recipeView.expandGrid.Width = 300;
  1428. }
  1429. else
  1430. {
  1431. recipeView.expandGrid.Width = 30;
  1432. }
  1433. }
  1434. private void OnUnload()
  1435. {
  1436. //if (CurrentRecipeName == null || CurrentRecipeName == "")
  1437. //{
  1438. // return;
  1439. //}
  1440. //if (WPFMessageBox.ShowQuestion($"Is Save Recipe {CurrentRecipeName}", "", false) == MessageBoxResult.Yes)
  1441. //{
  1442. // OnSaveRecipe();
  1443. //}
  1444. }
  1445. private void OnClearRecipe()
  1446. {
  1447. for (int i = 0; i < rightGrid.ColumnDefinitions.Count; i++)
  1448. {
  1449. rightGrid.ColumnDefinitions[i].Width = new GridLength(75);
  1450. }
  1451. leftGrid.Children.Clear();
  1452. rightGrid.Children.Clear();
  1453. leftGrid.ColumnDefinitions.Clear();
  1454. rightGrid.ColumnDefinitions.Clear();
  1455. rightGrid.RowDefinitions.Clear();
  1456. leftGrid.RowDefinitions.Clear();
  1457. GC.Collect(); // This should pick up the control removed at a previous MouseDown
  1458. GC.WaitForPendingFinalizers(); // Doesn't help either
  1459. //rightGrid.Visibility = Visibility.Visible;
  1460. }
  1461. private void ExpandAllItems(ItemsControl control)
  1462. {
  1463. if (control == null)
  1464. {
  1465. return;
  1466. }
  1467. foreach (Object item in control.Items)
  1468. {
  1469. System.Windows.Controls.TreeViewItem treeItem = control.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
  1470. if (treeItem == null || !treeItem.HasItems)
  1471. {
  1472. continue;
  1473. }
  1474. treeItem.IsExpanded = true;
  1475. ExpandAllItems(treeItem as ItemsControl);
  1476. }
  1477. }
  1478. private bool RecipeNameIsOk(string recipeName)
  1479. {
  1480. if (recipeName.Contains(' '))
  1481. {
  1482. WPFMessageBox.ShowError("Recipe Name 包含空格,不符合规格");
  1483. return false;
  1484. }
  1485. if (recipeName.Length > 25)
  1486. {
  1487. WPFMessageBox.ShowError("Recipe Name 大于25个字符,不符合规格");
  1488. return false;
  1489. }
  1490. return true;
  1491. }
  1492. #endregion
  1493. }
  1494. }