RecipeViewModel.cs 76 KB

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