RecipeViewModel.cs 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118
  1. using Aitex.Core.Common.DeviceData;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.UI.View.Common;
  4. //using MECF.Framework.Common.CommonData;
  5. using MECF.Framework.Common.DataCenter;
  6. using MECF.Framework.Common.OperationCenter;
  7. using Microsoft.VisualBasic;
  8. using Newtonsoft.Json;
  9. using Prism.Commands;
  10. using Prism.Mvvm;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.IO;
  14. using System.Linq;
  15. using System.Reflection;
  16. using System.Threading;
  17. using System.Windows;
  18. using System.Windows.Controls;
  19. using System.Windows.Data;
  20. using System.Windows.Input;
  21. using System.Windows.Media;
  22. using System.Windows.Threading;
  23. using System.Xml;
  24. using Venus_Core;
  25. using Venus_Core.Attributes;
  26. using Venus_MainPages.PMs;
  27. using Venus_MainPages.Unity;
  28. using Venus_MainPages.Views;
  29. using Venus_Themes.CustomControls;
  30. using Venus_Themes.UserControls;
  31. using WPF.Themes.UserControls;
  32. namespace Venus_MainPages.ViewModels
  33. {
  34. public enum EPDType
  35. {
  36. Socket,
  37. WCF,
  38. None
  39. }
  40. internal class RecipeViewModel : BindableBase
  41. {
  42. #region 私有字段
  43. public string ModuleName = "PMA";
  44. private string m_CurrentRecipeName;
  45. private UiRecipeManager m_uiRecipeManager = new UiRecipeManager();
  46. private RecipeView recipeView;
  47. private TreeView treeViewRcpList;
  48. private Recipe m_currentRecipe;
  49. private string m_recipeType;
  50. private bool firstLoad=true;
  51. private WrapPanel headWrapPanel;
  52. private StackPanel bodyStackPanel;
  53. private List<SolidColorBrush> solidColorBrushes = new List<SolidColorBrush>()
  54. {
  55. new SolidColorBrush(Colors.Coral),
  56. new SolidColorBrush(Colors.Cyan),
  57. new SolidColorBrush(Colors.Honeydew)
  58. };
  59. private Grid currentRecipeGrid;
  60. private int copyIndex = -1;
  61. private List<string> EPDCfgList=new List<string> ();
  62. private EPDType currentEPDType=EPDType.None;
  63. private JetChamber currentChamber;
  64. private bool isInstalledEPD;
  65. #endregion
  66. #region 属性
  67. public string CurrentRecipeName
  68. {
  69. get { return m_CurrentRecipeName; }
  70. set { SetProperty(ref m_CurrentRecipeName, value); }
  71. }
  72. public Recipe CurrentRecipe
  73. {
  74. get { return m_currentRecipe; }
  75. set
  76. {
  77. m_currentRecipe = value;
  78. RecipeType = m_currentRecipe.Header.Type.ToString();
  79. }
  80. }
  81. public string RecipeType
  82. {
  83. get { return m_recipeType; }
  84. set { SetProperty(ref m_recipeType, value); }
  85. }
  86. #endregion
  87. #region 命令
  88. private DelegateCommand<Object> _MouseRightButtonDownCommand;
  89. public DelegateCommand<Object> MouseRightButtonDownCommand =>
  90. _MouseRightButtonDownCommand ?? (_MouseRightButtonDownCommand = new DelegateCommand<Object>(OnMouseRightButtonDown));
  91. private DelegateCommand<Object> _LoadedCommand;
  92. public DelegateCommand<Object> LoadedCommand =>
  93. _LoadedCommand ?? (_LoadedCommand = new DelegateCommand<Object>(OnLoaded));
  94. private DelegateCommand _SaveRecipeCommand;
  95. public DelegateCommand SaveRecipeCommand =>
  96. _SaveRecipeCommand ?? (_SaveRecipeCommand = new DelegateCommand(OnSaveRecipe));
  97. private DelegateCommand _AddStepCommand;
  98. public DelegateCommand AddStepCommand =>
  99. _AddStepCommand ?? (_AddStepCommand = new DelegateCommand(OnAddStep));
  100. private DelegateCommand _DeleteStepCommand;
  101. public DelegateCommand DeleteStepCommand =>
  102. _DeleteStepCommand ?? (_DeleteStepCommand = new DelegateCommand(OnDeleteStep));
  103. #endregion
  104. #region 构造函数
  105. public RecipeViewModel()
  106. {
  107. }
  108. #endregion
  109. #region 命令方法
  110. private void OnAddStep()
  111. {
  112. if (CurrentRecipe != null)
  113. {
  114. var index = currentRecipeGrid.ColumnDefinitions.Count;
  115. RecipeStep recipeStep;
  116. if (copyIndex == -1)
  117. {
  118. recipeStep = new RecipeStep();
  119. switch (currentChamber)
  120. {
  121. case JetChamber.Venus:
  122. case JetChamber.Kepler2300:
  123. recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
  124. recipeStep.LstUnit.Add(new TCPUnit());
  125. recipeStep.LstUnit.Add(new BiasUnit());
  126. recipeStep.LstUnit.Add(new GasControlUnit());
  127. recipeStep.LstUnit.Add(new ESCHVUnit());
  128. recipeStep.LstUnit.Add(new ProcessKitUnit());
  129. break;
  130. case JetChamber.Kepler2200A:
  131. recipeStep.LstUnit.Add(new Kepler2200GasControlUnit());
  132. recipeStep.LstUnit.Add(new HeaterUnit());
  133. recipeStep.LstUnit.Add(new Kepler2200RFUnit());
  134. break;
  135. }
  136. CurrentRecipe.Steps.Insert(index - 1, recipeStep);
  137. }
  138. else
  139. {
  140. var t = JsonConvert.SerializeObject(CurrentRecipe);
  141. recipeStep = Recipe.Load(t).Steps[copyIndex - 1];
  142. CurrentRecipe.Steps.Insert(index - 1, recipeStep);
  143. }
  144. RecipeStepToGridColumn(recipeStep, currentRecipeGrid, index, true);
  145. for (int i = 1; i <= CurrentRecipe.Steps.Count; i++)
  146. {
  147. CurrentRecipe.Steps[i - 1].StepNo = i;
  148. }
  149. }
  150. }
  151. private void OnDeleteStep()
  152. {
  153. if (CurrentRecipe != null)
  154. {
  155. OnDeleteStep(CurrentRecipe.Steps.Count - 1);
  156. }
  157. }
  158. private void OnSaveRecipe()
  159. {
  160. SaveRecipe(CurrentRecipeName, RecipeUnity.RecipeToString(CurrentRecipe));
  161. LoadHeadWrapPanel(headWrapPanel, CurrentRecipe);
  162. }
  163. private void OnLoaded(Object myrecipeView)
  164. {
  165. if (firstLoad == true)
  166. {
  167. currentChamber = (JetChamber)Enum.Parse(typeof(JetChamber), QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.ChamberType").ToString());
  168. isInstalledEPD = bool.Parse(QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.EPD.IsEnabled").ToString()) ;
  169. firstLoad = false;
  170. recipeView = myrecipeView as RecipeView;
  171. treeViewRcpList = recipeView.treeViewRcpList;
  172. headWrapPanel = recipeView.headWrapPanel;
  173. bodyStackPanel = recipeView.bodyStackPanel;
  174. UpdateRecipeFileList();
  175. treeViewRcpList.SelectedItemChanged += TreeViewRcpList_SelectedItemChanged;
  176. DispatcherTimer timer = new DispatcherTimer();
  177. timer.Interval = TimeSpan.FromSeconds(1);
  178. timer.Tick += Timer_Tick; ;
  179. timer.Start();
  180. for (int i = 0; i < 5; i++)
  181. {
  182. InvokeClient.Instance.Service.DoOperation($"{ModuleName}.EndPoint.SearchCfg");
  183. Thread.Sleep(200);
  184. currentEPDType = (EPDType)System.Convert.ToInt32(QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.EPD.EPDType"));
  185. if (currentEPDType == EPDType.Socket)
  186. {
  187. EPDCfgList = (List<string>)QueryDataClient.Instance.Service.GetData($"{ModuleName}.EPDCfgList");
  188. }
  189. if (EPDCfgList != null)
  190. {
  191. break;
  192. }
  193. }
  194. }
  195. }
  196. private void Timer_Tick(object sender, EventArgs e)
  197. {
  198. }
  199. TreeViewFileItem selectedItem;
  200. private void TreeViewRcpList_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
  201. {
  202. selectedItem = e.NewValue as TreeViewFileItem;
  203. if (selectedItem == null)
  204. return;
  205. try
  206. {
  207. CurrentRecipeName = selectedItem.FileName;
  208. string xmlRecipeData = m_uiRecipeManager.LoadRecipe(ModuleName, selectedItem.FileName);
  209. if (xmlRecipeData == "")
  210. {
  211. treeViewRcpList.Items.Remove(selectedItem);
  212. return;
  213. }
  214. CurrentRecipe = Recipe.Load(xmlRecipeData);
  215. LoadHeadWrapPanel(headWrapPanel, CurrentRecipe);
  216. LoadRecipe(CurrentRecipe);
  217. }
  218. catch (Exception ex)
  219. {
  220. MessageBox.Show(string.Format(Application.Current.Resources["GlobalLableTitleRecipeEditor"].ToString(), ex.Message), Application.Current.Resources["GlobalLableTitleRecipeEditor"].ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
  221. }
  222. e.Handled = true;
  223. }
  224. public bool SaveRecipe(string recipeName, string recipeContent)
  225. {
  226. return m_uiRecipeManager.SaveRecipe(ModuleName, recipeName, recipeContent);
  227. }
  228. private void OnMouseRightButtonDown(Object treeView)
  229. {
  230. //treeViewRcpList = treeView as TreeView;
  231. treeViewRcpList.ContextMenu = new ContextMenu() { Background = new SolidColorBrush(Colors.AliceBlue)};
  232. MenuItem menuItem = new MenuItem();
  233. menuItem = new MenuItem();
  234. menuItem.Tag = "\\";
  235. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_CreateRecipe);
  236. menuItem.Header = "New Recipe";
  237. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  238. menuItem = new MenuItem();
  239. menuItem.Tag = "\\";
  240. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_DeleteRecipe);
  241. menuItem.Header = "Delete Recipe";
  242. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  243. menuItem = new MenuItem();
  244. menuItem.Tag = "\\";
  245. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_SaveAsRecipe);
  246. menuItem.Header = "Save As Recipe";
  247. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  248. menuItem = new MenuItem();
  249. menuItem.Tag = "\\";
  250. menuItem.Click += new RoutedEventHandler(menuItem_MouseClick_RenameRecipe);
  251. menuItem.Header = "Rename";
  252. treeViewRcpList.ContextMenu.Items.Add(menuItem);
  253. treeViewRcpList.ContextMenu.Visibility = Visibility.Visible;
  254. }
  255. private void menuItem_MouseClick_CreateRecipe(object sender, RoutedEventArgs e)
  256. {
  257. MenuItem mit = sender as MenuItem;
  258. string folderName = mit.Tag as string;
  259. PerformCreateRecipe(folderName);
  260. }
  261. private void PerformCreateRecipe(string folderName)
  262. {
  263. try
  264. {
  265. RecipeNameInputDlg dlg = new RecipeNameInputDlg(Application.Current.Resources["GlobalLableMsgInputRecipeName"].ToString())
  266. {
  267. Owner = Application.Current.MainWindow
  268. };
  269. if (dlg.ShowDialog() == true)
  270. {
  271. var recipeName = folderName + "\\" + dlg.InputText;
  272. RecipeType type = (RecipeType)Enum.Parse(typeof(RecipeType), dlg.SelectedType);
  273. string newRecipe =RecipeUnity.CreateRecipe(currentChamber,type, dlg.InputText);
  274. //string recipeContent = m_uiRecipeManager.GetRecipeTemplate(ModuleName);
  275. //m_uiRecipeManager.SaveAsRecipe(ModuleName, recipeName, m_uiRecipeManager.LoadRecipe("system",folderName));
  276. if (SaveAsRecipe(recipeName, newRecipe))
  277. {
  278. //UpdateRecipeFileList();
  279. //SelectRecipe(recipeName);
  280. treeViewRcpList.Items.Add(new TreeViewFileItem(dlg.InputText));
  281. }
  282. else
  283. {
  284. WPFMessageBox.ShowError("Error");
  285. }
  286. }
  287. }
  288. catch (Exception ex)
  289. {
  290. LOG.WriteExeption(ex);
  291. MessageBox.Show(string.Format(Application.Current.Resources["GlobalLableMsgRecipeCreateException"].ToString(), ex.Message), Application.Current.Resources["GlobalLableTitleRecipeEditor"].ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
  292. }
  293. }
  294. private void menuItem_MouseClick_DeleteRecipe(object sender, RoutedEventArgs e)
  295. {
  296. if (CurrentRecipe == null)
  297. {
  298. return;
  299. }
  300. if (WPFMessageBox.ShowQuestion($"Delete {CurrentRecipeName}?","删除后无法恢复!!!") == MessageBoxResult.Yes)
  301. {
  302. MenuItem mit = sender as MenuItem;
  303. //string recipename = mit.Header.ToString();
  304. m_uiRecipeManager.DeleteRecipe(ModuleName, CurrentRecipeName);
  305. //PerformCreateRecipe(folderName);
  306. treeViewRcpList.Items.Remove(selectedItem);
  307. }
  308. }
  309. private void menuItem_MouseClick_SaveAsRecipe(object sender, RoutedEventArgs e)
  310. {
  311. if (CurrentRecipe == null)
  312. {
  313. return;
  314. }
  315. var newName = Interaction.InputBox(" ", "Save As Recipe", CurrentRecipeName, -1, -1);
  316. if (newName != CurrentRecipeName && newName != "")
  317. {
  318. var newRecipe = CurrentRecipe;
  319. newRecipe.Header.Name = newName;
  320. newRecipe.Header.CreateTime = DateTime.Now.ToString();
  321. var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, newName + ".rcp");
  322. File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
  323. UpdateRecipeFileList();
  324. }
  325. }
  326. private void menuItem_MouseClick_RenameRecipe(object sender, RoutedEventArgs e)
  327. {
  328. if (CurrentRecipe == null)
  329. {
  330. return;
  331. }
  332. var newName= Interaction.InputBox(" ", "Rename Recipe", CurrentRecipeName, -1, -1);
  333. if (newName != CurrentRecipeName && newName!="")
  334. {
  335. var oldrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, CurrentRecipeName + ".rcp");
  336. var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, newName + ".rcp");
  337. CurrentRecipe.Header.Name = newName;
  338. SaveRecipe(CurrentRecipeName, RecipeUnity.RecipeToString(CurrentRecipe));
  339. File.Move(oldrecipePath, newrecipePath);
  340. UpdateRecipeFileList();
  341. }
  342. }
  343. public bool SaveAsRecipe(string recipeName, string recipeContent)
  344. {
  345. return m_uiRecipeManager.SaveAsRecipe(ModuleName, recipeName, recipeContent);
  346. }
  347. public string GetXmlRecipeList()
  348. {
  349. return m_uiRecipeManager.GetXmlRecipeList(ModuleName, true) ?? "";
  350. }
  351. void CreateTreeViewItems(XmlElement curElementNode, ItemsControl itemsControl)
  352. {
  353. foreach (XmlElement ele in curElementNode.ChildNodes)
  354. {
  355. if (ele.Name == "File")
  356. {
  357. string fileName = ele.Attributes["Name"].Value;
  358. fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
  359. TreeViewFileItem item = new TreeViewFileItem(ele.Attributes["Name"].Value);
  360. item.Tag = ele.Attributes["Name"].Value;
  361. //item.ToolTip = fileName;
  362. itemsControl.Items.Add(item);
  363. }
  364. else if (ele.Name == "Folder")
  365. {
  366. string folderName = ele.Attributes["Name"].Value;
  367. folderName = folderName.Substring(folderName.LastIndexOf('\\') + 1);
  368. TreeViewFolderItem item = new TreeViewFolderItem(folderName);
  369. item.Tag = ele.Attributes["Name"].Value;
  370. CreateTreeViewItems(ele, item);
  371. item.IsExpanded = false;
  372. itemsControl.Items.Add(item);
  373. }
  374. }
  375. }
  376. private IEnumerable<string> GetFilesNames(string path)
  377. {
  378. return Directory.GetFiles(path, "*.rcp")
  379. .Select(Path.GetFileNameWithoutExtension);
  380. }
  381. private void LoadHeadWrapPanel(WrapPanel HeadWrapPanel, Recipe recipe)
  382. {
  383. HeadWrapPanel.Children.Clear();
  384. Type type = recipe.Header.GetType();
  385. foreach (var propertyInfo in type.GetProperties())
  386. {
  387. TextBlock textBlock = new TextBlock();
  388. textBlock.FontSize = 15;
  389. //textBlock.Width = 100;
  390. textBlock.Text = propertyInfo.Name + ":";
  391. textBlock.Margin = new Thickness(15, 0, 0, 0);
  392. textBlock.VerticalAlignment = VerticalAlignment.Center;
  393. HeadWrapPanel.Children.Add(textBlock);
  394. Binding binding = new Binding()
  395. {
  396. Source = recipe.Header, // 数据源
  397. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  398. Mode = BindingMode.TwoWay, // 绑定模式
  399. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  400. };
  401. var propertyTypeName = propertyInfo.PropertyType.Name;
  402. var propertyInfoName = propertyInfo.Name;
  403. Control control = new Control();
  404. switch (propertyInfoName)
  405. {
  406. case "ChamberType":
  407. case "Type":
  408. control = new ComboBox();
  409. control.Height = 23;
  410. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  411. ItemsControlHelper.SetEnumValuesToItemsSource(control, true);
  412. break;
  413. case "ChuckRecipe":
  414. control = new ComboBox()
  415. {
  416. ItemsSource = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList().Where(item => item.ToLower().Contains("chuck")&& (item.ToLower().Contains("dechuck")==false))
  417. };
  418. control.Height = 23;
  419. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  420. break;
  421. case "DechuckRecipe":
  422. control = new ComboBox()
  423. {
  424. ItemsSource= GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList().Where(item=>item.ToLower().Contains("dechuck"))
  425. };
  426. control.Height = 23;
  427. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  428. break;
  429. default:
  430. control = new TextBox();
  431. control.Margin = new Thickness(1, 0, 0, 0);
  432. control.BorderThickness = new Thickness(0, 0, 0, 1);
  433. //control.BorderBrush = Brushes.Black;
  434. control.FontSize = 15;
  435. control.Foreground = Brushes.Green;
  436. control.Background = Brushes.Transparent;
  437. control.VerticalAlignment = VerticalAlignment.Center;
  438. control.MinWidth = 15;
  439. control.SetBinding(TextBox.TextProperty, binding);
  440. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  441. if (objAttrs.Length > 0)
  442. {
  443. (control as TextBox).IsReadOnly = true;
  444. }
  445. break;
  446. }
  447. //switch (propertyTypeName)
  448. //{
  449. // case "Int32":
  450. // case "String":
  451. // control = new TextBox();
  452. // control.Margin = new Thickness(1, 0, 0, 0);
  453. // control.BorderThickness = new Thickness(0, 0, 0, 1);
  454. // //control.BorderBrush = Brushes.Black;
  455. // control.FontSize = 15;
  456. // control.Foreground = Brushes.Green;
  457. // control.Background = Brushes.Transparent;
  458. // control.VerticalAlignment = VerticalAlignment.Center;
  459. // control.MinWidth = 15;
  460. // control.SetBinding(TextBox.TextProperty, binding);
  461. // object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  462. // if (objAttrs.Length > 0)
  463. // {
  464. // (control as TextBox).IsReadOnly = true;
  465. // }
  466. // break;
  467. // case "Boolean":
  468. // control = new CheckBox();
  469. // control.SetBinding(CheckBox.IsCheckedProperty, binding);
  470. // break;
  471. // default:
  472. // control = new ComboBox();
  473. // control.Height = 23;
  474. // control.SetBinding(ComboBox.SelectedItemProperty, binding);
  475. // ItemsControlHelper.SetEnumValuesToItemsSource(control, true);
  476. // break;
  477. //}
  478. HeadWrapPanel.Children.Add(control);
  479. }
  480. }
  481. private void MenuItemLeftInsert_Click(object sender, RoutedEventArgs e)
  482. {
  483. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  484. int insertIndex = Convert.ToInt32(t.Text);
  485. OnAddStep(insertIndex);
  486. }
  487. private void MenuItemRightInsert_Click(object sender, RoutedEventArgs e)
  488. {
  489. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  490. int insertIndex = Convert.ToInt32(t.Text);
  491. OnAddStep(insertIndex + 1);
  492. }
  493. private void MenuItemDelete_Click(object sender, RoutedEventArgs e)
  494. {
  495. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  496. int deleteIndex = Convert.ToInt32(t.Text);
  497. OnDeleteStep(deleteIndex - 1);
  498. }
  499. private void MenuItemCopy_Click(object sender, RoutedEventArgs e)
  500. {
  501. var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
  502. copyIndex = Convert.ToInt32(t.Text);
  503. }
  504. #endregion
  505. #region 私有方法
  506. private void RecipeStepToGridColumn(RecipeStep recipeStep, Grid grid, int index, bool isInsert)
  507. {
  508. int location = 1;
  509. if (isInsert == true)
  510. {
  511. location -= 1;
  512. }
  513. Type recipeType = recipeStep.GetType();
  514. int cycleCount = 1;
  515. if (index == 0)
  516. {
  517. cycleCount = 2;
  518. }
  519. for (int j = 0; j < cycleCount; j++)
  520. {
  521. int i = 0;
  522. ColumnDefinition col1 = new ColumnDefinition();
  523. //col1.MinWidth = 50;
  524. grid.ColumnDefinitions.Insert(index, col1);
  525. Binding stepcheckbinding = null;
  526. //grid.MinWidth = 200;
  527. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  528. {
  529. string propertyInfoName = propertyInfo.Name;
  530. string propertyTypeName = propertyInfo.PropertyType.Name;
  531. if (propertyInfoName != "LstUnit")
  532. {
  533. if (index == 0 && grid.ColumnDefinitions.Count == 1)
  534. {
  535. RowDefinition row1 = new RowDefinition();
  536. grid.RowDefinitions.Add(row1);
  537. if ((propertyInfoName == "EPDConfig" || propertyInfoName == "MinEndPointTime" || propertyInfoName == "MaxEndPointTime") && isInstalledEPD == false)
  538. {
  539. row1.Height = new GridLength(0);
  540. }
  541. }
  542. if (grid.ColumnDefinitions.Count == 1 && j == 0)
  543. {
  544. TextBox textBlock = new TextBox();
  545. textBlock.IsReadOnly = true;
  546. textBlock.Text = propertyInfoName;
  547. grid.Children.Add(textBlock);
  548. textBlock.Background = new SolidColorBrush(Colors.BurlyWood);
  549. Grid.SetRow(textBlock, i);
  550. Grid.SetColumn(textBlock, 0);
  551. }
  552. else
  553. {
  554. Binding binding = new Binding()
  555. {
  556. Source = recipeStep, // 数据源
  557. Path = new PropertyPath(propertyInfoName), // 需绑定的数据源属性名
  558. Mode = BindingMode.TwoWay, // 绑定模式
  559. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  560. };
  561. switch (propertyTypeName)
  562. {
  563. case "Int32":
  564. case "String":
  565. if (propertyInfoName == "EPDConfig")
  566. {
  567. if (currentEPDType == EPDType.Socket)
  568. {
  569. ComboBox EPDcomboBox = new ComboBox();
  570. EPDcomboBox.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  571. EPDcomboBox.Background = new SolidColorBrush(Colors.Black);
  572. EPDcomboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  573. EPDcomboBox.ItemsSource = EPDCfgList;
  574. grid.Children.Add(EPDcomboBox);
  575. Grid.SetRow(EPDcomboBox, i);
  576. Grid.SetColumn(EPDcomboBox, index + location);
  577. EPDcomboBox.DropDownOpened += EPDcomboBox_DropDownOpened;
  578. }
  579. else if (currentEPDType == EPDType.WCF)
  580. {
  581. Button EPDButton = new Button();
  582. EPDButton.Content = "EndPoint";
  583. EPDButton.Cursor = Cursors.Hand;
  584. EPDButton.Tag = $"{CurrentRecipeName}.{(index + location).ToString()}";
  585. EPDButton.Style = null;
  586. EPDButton.Click += EPDButton_Click;
  587. grid.Children.Add(EPDButton);
  588. Grid.SetRow(EPDButton, i);
  589. Grid.SetColumn(EPDButton, index + location);
  590. }
  591. break;
  592. }
  593. TextBox textBox = new TextBox();
  594. textBox.HorizontalContentAlignment = HorizontalAlignment.Center;
  595. textBox.VerticalContentAlignment = VerticalAlignment.Center;
  596. if (stepcheckbinding == null)
  597. {
  598. textBox.IsEnabled = true;
  599. }
  600. else
  601. {
  602. textBox.SetBinding(TextBox.IsEnabledProperty, stepcheckbinding);
  603. }
  604. textBox.SetBinding(TextBox.TextProperty, binding);
  605. grid.Children.Add(textBox);
  606. Grid.SetRow(textBox, i);
  607. Grid.SetColumn(textBox, index + location);
  608. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  609. if (objAttrs.Length > 0)
  610. {
  611. textBox.IsReadOnly = true;
  612. ContextMenu contextmenu = new ContextMenu();
  613. textBox.ContextMenu = contextmenu;
  614. MenuItem menuItemDelete = new MenuItem();
  615. menuItemDelete.Header = "删除";
  616. menuItemDelete.Click += MenuItemDelete_Click;
  617. MenuItem menuItemLeftInsert = new MenuItem();
  618. menuItemLeftInsert.Header = "左插入";
  619. menuItemLeftInsert.Click += MenuItemLeftInsert_Click;
  620. MenuItem menuItemRightInsert = new MenuItem();
  621. menuItemRightInsert.Header = "右插入";
  622. menuItemRightInsert.Click += MenuItemRightInsert_Click;
  623. MenuItem menuItemCopy = new MenuItem();
  624. menuItemCopy.Tag = textBox.Text;
  625. menuItemCopy.Header = "复制";
  626. menuItemCopy.Click += MenuItemCopy_Click;
  627. contextmenu.Items.Add(menuItemCopy);
  628. contextmenu.Items.Add(menuItemDelete);
  629. contextmenu.Items.Add(menuItemLeftInsert);
  630. contextmenu.Items.Add(menuItemRightInsert);
  631. }
  632. break;
  633. case "Boolean":
  634. CheckBox checkBox = new CheckBox();
  635. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  636. grid.Children.Add(checkBox);
  637. Grid.SetRow(checkBox, i);
  638. Grid.SetColumn(checkBox, index + location);
  639. //if (stepcheckbinding == null)
  640. //{
  641. // stepcheckbinding = new Binding
  642. // {
  643. // Source = checkBox, // 数据源
  644. // Path = new PropertyPath("IsChecked"), // 需绑定的数据源属性名
  645. // Mode = BindingMode.TwoWay, // 绑定模式
  646. // UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  647. // };
  648. //}
  649. //else
  650. //{
  651. //}
  652. if (stepcheckbinding == null)
  653. {
  654. checkBox.IsEnabled = true;
  655. }
  656. else
  657. {
  658. checkBox.SetBinding(TextBox.IsEnabledProperty, stepcheckbinding);
  659. }
  660. break;
  661. default:
  662. ComboBox comboBox = new ComboBox();
  663. comboBox.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  664. comboBox.Background = new SolidColorBrush(Colors.Black);
  665. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  666. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  667. grid.Children.Add(comboBox);
  668. Grid.SetRow(comboBox, i);
  669. Grid.SetColumn(comboBox, index + location);
  670. if (stepcheckbinding == null)
  671. {
  672. comboBox.IsEnabled = true;
  673. }
  674. else
  675. {
  676. comboBox.SetBinding(TextBox.IsEnabledProperty, stepcheckbinding);
  677. }
  678. break;
  679. }
  680. }
  681. i++;
  682. }
  683. }
  684. int k = 0;
  685. recipeStep.LstUnit.ToList().ForEach(x =>
  686. {
  687. Type unitType = x.GetType();
  688. Binding checkbinding = null;
  689. foreach (PropertyInfo propertyInfo in unitType.GetProperties())
  690. {
  691. if (index == 0 && grid.ColumnDefinitions.Count == 1)
  692. {
  693. RowDefinition row1 = new RowDefinition();
  694. grid.RowDefinitions.Add(row1);
  695. }
  696. if (grid.ColumnDefinitions.Count == 1 && j == 0)
  697. {
  698. TextBox textBlock = new TextBox();
  699. textBlock.IsReadOnly = true;
  700. switch (propertyInfo.Name)
  701. {
  702. case "Gas1":
  703. var data1 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas1");
  704. textBlock.Text = $"{propertyInfo.Name}({data1.DisplayName},{data1.Scale})";
  705. break;
  706. case "Gas2":
  707. var data2 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas2");
  708. textBlock.Text = $"{propertyInfo.Name}({data2.DisplayName},{data2.Scale})";
  709. break;
  710. case "Gas3":
  711. var data3 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas3");
  712. textBlock.Text = $"{propertyInfo.Name}({data3.DisplayName},{data3.Scale})";
  713. break;
  714. case "Gas4":
  715. var data4 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas4");
  716. textBlock.Text = $"{propertyInfo.Name}({data4.DisplayName},{data4.Scale})";
  717. break;
  718. case "Gas5":
  719. var data5 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas5");
  720. textBlock.Text = $"{propertyInfo.Name}({data5.DisplayName},{data5.Scale})";
  721. break;
  722. case "Gas6":
  723. var data6 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas6");
  724. textBlock.Text = $"{propertyInfo.Name}({data6.DisplayName},{data6.Scale})";
  725. break;
  726. case "Gas7":
  727. var data7 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas7");
  728. textBlock.Text = $"{propertyInfo.Name}({data7.DisplayName},{data7.Scale})";
  729. break;
  730. case "Gas8":
  731. var data8 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas8");
  732. textBlock.Text = $"{propertyInfo.Name}({data8.DisplayName},{data8.Scale})";
  733. break;
  734. case "HeaterPressure":
  735. textBlock.Text = "Pressure(Pa)";
  736. break;
  737. case "HeaterTemp":
  738. textBlock.Text = "Heater Temp(℃)";
  739. break;
  740. case "HeaterRatio":
  741. textBlock.Text = "Heater Ratio";
  742. break;
  743. default:
  744. textBlock.Text = propertyInfo.Name;
  745. break;
  746. }
  747. textBlock.Background = solidColorBrushes[k % 3];
  748. grid.Children.Add(textBlock);
  749. Grid.SetRow(textBlock, i);
  750. Grid.SetColumn(textBlock, 0);
  751. }
  752. else
  753. {
  754. Binding binding = new Binding()
  755. {
  756. Source = recipeStep.LstUnit[k], // 数据源
  757. //Path = new PropertyPath($"LstUnit[{k}]." + propertyInfo.Name), // 需绑定的数据源属性名
  758. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  759. Mode = BindingMode.TwoWay, // 绑定模式
  760. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  761. };
  762. var item = propertyInfo.PropertyType.Name;
  763. if (propertyInfo.Name == "UnitName")
  764. {
  765. TextBox textBlock1 = new TextBox();
  766. textBlock1.HorizontalContentAlignment = HorizontalAlignment.Center;
  767. textBlock1.VerticalContentAlignment =VerticalAlignment.Center;
  768. textBlock1.Text = propertyInfo.GetValue(x).ToString();
  769. textBlock1.IsReadOnly = true;
  770. grid.Children.Add(textBlock1);
  771. Grid.SetRow(textBlock1, i);
  772. Grid.SetColumn(textBlock1, index + location);
  773. }
  774. else
  775. {
  776. switch (item)
  777. {
  778. case "Int32":
  779. case "String":
  780. TextBox textBox = new TextBox();
  781. textBox.HorizontalContentAlignment = HorizontalAlignment.Center;
  782. textBox.VerticalContentAlignment = VerticalAlignment.Center;
  783. if (checkbinding == null)
  784. {
  785. textBox.IsEnabled = true;
  786. }
  787. else
  788. {
  789. textBox.SetBinding(TextBox.IsEnabledProperty, checkbinding);
  790. }
  791. switch (propertyInfo.Name)
  792. {
  793. case "Gas1":
  794. var data1 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas1");
  795. TextBoxMaxValue.SetMaxValue(textBox, (int)data1.Scale);
  796. break;
  797. case "Gas2":
  798. var data2 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas2");
  799. TextBoxMaxValue.SetMaxValue(textBox, (int)data2.Scale);
  800. break;
  801. case "Gas3":
  802. var data3 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas3");
  803. break;
  804. case "Gas4":
  805. var data4 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas4");
  806. break;
  807. case "Gas5":
  808. var data5 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas5");
  809. break;
  810. case "Gas6":
  811. var data6 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas6");
  812. break;
  813. case "Gas7":
  814. var data7 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas7");
  815. break;
  816. case "Gas8":
  817. var data8 = (AITMfcData)QueryDataClient.Instance.Service.GetData($"{ModuleName}.MfcGas8");
  818. break;
  819. }
  820. textBox.SetBinding(TextBox.TextProperty, binding);
  821. grid.Children.Add(textBox);
  822. Grid.SetRow(textBox, i);
  823. Grid.SetColumn(textBox, index + location);
  824. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  825. if (objAttrs.Length > 0)
  826. {
  827. textBox.IsReadOnly = true;
  828. }
  829. break;
  830. case "Boolean":
  831. CheckBox checkBox = new CheckBox();
  832. if (checkbinding == null)
  833. {
  834. checkbinding = new Binding
  835. {
  836. Source = checkBox, // 数据源
  837. Path = new PropertyPath("IsChecked"), // 需绑定的数据源属性名
  838. Mode = BindingMode.TwoWay, // 绑定模式
  839. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  840. };
  841. }
  842. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  843. grid.Children.Add(checkBox);
  844. Grid.SetRow(checkBox, i);
  845. Grid.SetColumn(checkBox, index + location);
  846. break;
  847. default:
  848. ComboBox comboBox = new ComboBox();
  849. comboBox.BorderBrush = Brushes.Gray;
  850. comboBox.Style = (Style)recipeView.FindResource("customeComboBoxStyle");
  851. if (checkbinding == null)
  852. {
  853. comboBox.IsEnabled = true;
  854. }
  855. else
  856. {
  857. comboBox.SetBinding(TextBox.IsEnabledProperty, checkbinding);
  858. }
  859. comboBox.Background = Brushes.White;
  860. string path = propertyInfo.Name;
  861. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  862. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  863. grid.Children.Add(comboBox);
  864. Grid.SetRow(comboBox, i);
  865. Grid.SetColumn(comboBox, index + location);
  866. break;
  867. }
  868. }
  869. }
  870. i++;
  871. }
  872. k++;
  873. });
  874. //index++;
  875. }
  876. }
  877. private void EPDcomboBox_DropDownOpened(object sender, EventArgs e)
  878. {
  879. }
  880. private void EPDButton_Click(object sender, RoutedEventArgs e)
  881. {
  882. Button button = sender as Button;
  883. string para = button.Tag.ToString();
  884. int stepno = Convert.ToInt32(para.Split('.')[1])-1;
  885. var endpointconfigitem = new MECF.Framework.Common.CommonData.EndPointConfigItem();
  886. if (CurrentRecipe.Steps[stepno].EPDConfig!=null && CurrentRecipe.Steps[stepno].EPDConfig.Length>20)
  887. {
  888. endpointconfigitem.SetValue(CurrentRecipe.Steps[stepno].EPDConfig);
  889. }
  890. (new EndPointDlg(para, endpointconfigitem,CurrentRecipe)).ShowDialog();
  891. }
  892. private void UpdateRecipeFileList()
  893. {
  894. XmlDocument doc = new XmlDocument();
  895. doc.LoadXml(GetXmlRecipeList());
  896. treeViewRcpList.Items.Clear();
  897. CreateTreeViewItems(doc.DocumentElement, this.treeViewRcpList);
  898. }
  899. private void LoadRecipe(Recipe recipe)
  900. {
  901. copyIndex = -1;
  902. bodyStackPanel.Children.Clear();
  903. //CurrentRecipe = null;
  904. GC.Collect(); // This should pick up the control removed at a previous MouseDown
  905. GC.WaitForPendingFinalizers(); // Doesn't help either
  906. GC.Collect();
  907. GC.WaitForPendingFinalizers(); // Doesn't help either
  908. CurrentRecipe = recipe;
  909. Grid grid = new Grid();
  910. grid.Margin = new Thickness(15);
  911. //index = 0;
  912. for (int i = 0; i < recipe.Steps.Count; i++)
  913. {
  914. RecipeStepToGridColumn(recipe.Steps[i], grid, i, false);
  915. }
  916. bodyStackPanel.Children.Add(grid);
  917. currentRecipeGrid = grid;
  918. }
  919. private void OnAddStep(int index)
  920. {
  921. if (CurrentRecipe != null)
  922. {
  923. RecipeStep recipeStep;
  924. if (copyIndex == -1)
  925. {
  926. recipeStep = new RecipeStep();
  927. //recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
  928. //recipeStep.LstUnit.Add(new TCPUnit());
  929. //recipeStep.LstUnit.Add(new BiasUnit());
  930. //recipeStep.LstUnit.Add(new GasControlUnit());
  931. //recipeStep.LstUnit.Add(new ESCHVUnit());
  932. //recipeStep.LstUnit.Add(new ProcessKitUnit());
  933. switch (currentChamber)
  934. {
  935. case JetChamber.Venus:
  936. case JetChamber.Kepler2300:
  937. recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
  938. recipeStep.LstUnit.Add(new TCPUnit());
  939. recipeStep.LstUnit.Add(new BiasUnit());
  940. recipeStep.LstUnit.Add(new GasControlUnit());
  941. recipeStep.LstUnit.Add(new ESCHVUnit());
  942. recipeStep.LstUnit.Add(new ProcessKitUnit());
  943. break;
  944. case JetChamber.Kepler2200A:
  945. recipeStep.LstUnit.Add(new Kepler2200GasControlUnit());
  946. recipeStep.LstUnit.Add(new HeaterUnit());
  947. recipeStep.LstUnit.Add(new Kepler2200RFUnit());
  948. break;
  949. }
  950. CurrentRecipe.Steps.Insert(index - 1, recipeStep);
  951. }
  952. else
  953. {
  954. var t = JsonConvert.SerializeObject(CurrentRecipe);
  955. recipeStep = Recipe.Load(t).Steps[copyIndex - 1];
  956. CurrentRecipe.Steps.Insert(index - 1, recipeStep);
  957. }
  958. RecipeStepToGridColumn(recipeStep, currentRecipeGrid, index, true);
  959. for (int i = 1; i <= CurrentRecipe.Steps.Count; i++)
  960. {
  961. CurrentRecipe.Steps[i - 1].StepNo = i;
  962. }
  963. }
  964. }
  965. private void OnDeleteStep(int index)
  966. {
  967. if (CurrentRecipe != null && CurrentRecipe.Steps.Count > 1)
  968. {
  969. CurrentRecipe.Steps.RemoveAt(index);
  970. currentRecipeGrid.Children.RemoveRange(currentRecipeGrid.RowDefinitions.Count * (index + 1), currentRecipeGrid.RowDefinitions.Count);
  971. currentRecipeGrid.ColumnDefinitions.RemoveAt(index);
  972. for (int i = 1; i <= CurrentRecipe.Steps.Count; i++)
  973. {
  974. CurrentRecipe.Steps[i - 1].StepNo = i;
  975. }
  976. }
  977. }
  978. #endregion
  979. }
  980. }