RecipeEditorControlViewModel.cs 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Media;
  11. using Venus_Core;
  12. using Venus_Core.Attributes;
  13. namespace Aitex.UI.RecipeEditor
  14. {
  15. public class RecipeEditorControlViewModel : INotifyPropertyChanged
  16. {
  17. //当前选中的配方
  18. private Recipe m_currentRecipe;
  19. public Recipe CurrentRecipe
  20. {
  21. get { return m_currentRecipe; }
  22. set { m_currentRecipe = value; InvokePropertyChanged("CurrentRecipe"); }
  23. }
  24. public StackPanel GridStackPanel { get; set; } //step容器
  25. List<SolidColorBrush> solidColorBrushes = new List<SolidColorBrush>();//step模块颜色
  26. public WrapPanel HeadWrapPanel { get; set; } //head容器
  27. Grid currentGrid;
  28. public RecipeEditorControlViewModel()
  29. {
  30. }
  31. public void OnAddStep()
  32. {
  33. if (CurrentRecipe != null)
  34. {
  35. RecipeStep recipeStep = new RecipeStep();
  36. recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
  37. recipeStep.LstUnit.Add(new TCPUnit());
  38. recipeStep.LstUnit.Add(new BiasUnit());
  39. recipeStep.LstUnit.Add(new GasControlUnit());
  40. recipeStep.LstUnit.Add(new ESCHVUnit());
  41. recipeStep.LstUnit.Add(new ProcessKitUnit());
  42. recipeStep.StepNo = currentGrid.ColumnDefinitions.Count;
  43. CurrentRecipe.Steps.Add(recipeStep);
  44. //var item = RecipeStepToGrid(recipeStep);
  45. //GridStackPanel.Children.Add(item.Item1);
  46. RecipeStepToGridColumn(recipeStep, currentGrid);
  47. }
  48. }
  49. public void OnDeleteStep()
  50. {
  51. if (CurrentRecipe != null&& CurrentRecipe.Steps.Count>0)
  52. {
  53. CurrentRecipe.Steps.RemoveAt(CurrentRecipe.Steps.Count - 1);
  54. currentGrid.ColumnDefinitions.RemoveAt(currentGrid.ColumnDefinitions.Count-1);
  55. }
  56. }
  57. /// <summary>
  58. /// 选中recipe,显示界面
  59. /// </summary>
  60. /// <param name="recipe"></param>
  61. public void LoadRecipe(Recipe recipe)
  62. {
  63. GridStackPanel.Children.Clear();
  64. CurrentRecipe = null;
  65. GC.Collect(); // This should pick up the control removed at a previous MouseDown
  66. GC.WaitForPendingFinalizers(); // Doesn't help either
  67. GC.Collect();
  68. GC.WaitForPendingFinalizers(); // Doesn't help either
  69. CurrentRecipe = recipe;
  70. Grid grid = new Grid();
  71. GridOptions.SetShowBorder(grid, true);
  72. GridOptions.SetLineBrush(grid, Brushes.White);
  73. GridOptions.SetLineThickness(grid, 1);
  74. recipe.Steps.ToList().ForEach(x =>
  75. {
  76. RecipeStepToGridColumn(x,grid);
  77. });
  78. GridStackPanel.Children.Add(grid);
  79. LoadHeadWrapPanel(recipe);
  80. currentGrid = grid;
  81. }
  82. /// <summary>
  83. /// 选中recipe,头部界面显示
  84. /// </summary>
  85. /// <param name="recipe"></param>
  86. private void LoadHeadWrapPanel(Recipe recipe)
  87. {
  88. HeadWrapPanel.Children.Clear();
  89. Type type = recipe.Header.GetType();
  90. foreach (var propertyInfo in type.GetProperties())
  91. {
  92. TextBlock textBlock = new TextBlock();
  93. textBlock.FontSize = 15;
  94. //textBlock.Width = 100;
  95. textBlock.Text = propertyInfo.Name + ":";
  96. textBlock.Margin = new Thickness(15, 0, 0, 0);
  97. textBlock.VerticalAlignment = VerticalAlignment.Center;
  98. HeadWrapPanel.Children.Add(textBlock);
  99. Binding binding = new Binding()
  100. {
  101. Source = recipe.Header, // 数据源
  102. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  103. Mode = BindingMode.TwoWay, // 绑定模式
  104. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  105. };
  106. var propertyTypeName = propertyInfo.PropertyType.Name;
  107. var propertyInfoName=propertyInfo.Name;
  108. Control control = new Control();
  109. switch (propertyTypeName)
  110. {
  111. case "Int32":
  112. case "String":
  113. control = new TextBox();
  114. control.Margin = new Thickness(1, 0, 0, 0);
  115. control.BorderThickness = new Thickness(0,0,0,1);
  116. //control.BorderBrush = Brushes.Black;
  117. control.FontSize = 15;
  118. control.Foreground = Brushes.Green;
  119. control.Background = Brushes.Transparent;
  120. control.VerticalAlignment = VerticalAlignment.Center;
  121. control.MinWidth = 15;
  122. //control.Width = 200;
  123. control.SetBinding(TextBox.TextProperty, binding);
  124. //if (propertyInfoName == "Name" || propertyInfoName == "CreateTime" || propertyInfoName == "LastModifiedBy")
  125. //{
  126. // (control as TextBox).IsReadOnly = true;
  127. //}
  128. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  129. if (objAttrs.Length > 0)
  130. {
  131. (control as TextBox).IsReadOnly = true;
  132. }
  133. break;
  134. case "Boolean":
  135. control = new CheckBox();
  136. control.SetBinding(CheckBox.IsCheckedProperty, binding);
  137. break;
  138. default:
  139. control = new ComboBox();
  140. control.Height = 23;
  141. control.SetBinding(ComboBox.SelectedItemProperty, binding);
  142. ItemsControlHelper.SetEnumValuesToItemsSource(control, true);
  143. break;
  144. }
  145. HeadWrapPanel.Children.Add(control);
  146. }
  147. }
  148. private void RecipeStepToGridColumn(RecipeStep recipeStep, Grid grid)
  149. {
  150. Type recipeType = recipeStep.GetType();
  151. int i = 0;
  152. if (grid.ColumnDefinitions.Count == 0)
  153. {
  154. ColumnDefinition col1 = new ColumnDefinition();//Key
  155. grid.ColumnDefinitions.Add(col1);
  156. }
  157. ColumnDefinition col2 = new ColumnDefinition();//Value
  158. grid.ColumnDefinitions.Add(col2);
  159. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  160. {
  161. string propertyInfoName = propertyInfo.Name;
  162. string propertyTypeName = propertyInfo.PropertyType.Name;
  163. if (propertyInfoName != "LstUnit")
  164. {
  165. RowDefinition row1 = new RowDefinition();
  166. grid.RowDefinitions.Add(row1);
  167. Binding binding = new Binding()
  168. {
  169. Source = recipeStep, // 数据源
  170. Path = new PropertyPath(propertyInfoName), // 需绑定的数据源属性名
  171. Mode = BindingMode.TwoWay, // 绑定模式
  172. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  173. };
  174. switch (propertyTypeName)
  175. {
  176. case "Int32":
  177. case "String":
  178. TextBox textBox = new TextBox();
  179. textBox.SetBinding(TextBox.TextProperty, binding);
  180. grid.Children.Add(textBox);
  181. Grid.SetRow(textBox, i);
  182. Grid.SetColumn(textBox, grid.ColumnDefinitions.Count - 1);
  183. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  184. if (objAttrs.Length > 0)
  185. {
  186. textBox.IsReadOnly = true;
  187. }
  188. break;
  189. case "Boolean":
  190. CheckBox checkBox = new CheckBox();
  191. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  192. grid.Children.Add(checkBox);
  193. Grid.SetRow(checkBox, i);
  194. Grid.SetColumn(checkBox, grid.ColumnDefinitions.Count - 1);
  195. break;
  196. default:
  197. ComboBox comboBox = new ComboBox();
  198. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  199. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  200. grid.Children.Add(comboBox);
  201. Grid.SetRow(comboBox, i);
  202. Grid.SetColumn(comboBox, grid.ColumnDefinitions.Count - 1);
  203. if (propertyInfo.Name == "PressureUnitMode")
  204. {
  205. comboBox.SelectionChanged += ComboBox_SelectionChanged;
  206. }
  207. break;
  208. }
  209. if (grid.ColumnDefinitions.Count == 2)
  210. {
  211. TextBlock textBlock = new TextBlock();
  212. textBlock.Text = propertyInfoName;
  213. grid.Children.Add(textBlock);
  214. Grid.SetRow(textBlock, i);
  215. Grid.SetColumn(textBlock, 0);
  216. }
  217. i++;
  218. }
  219. }
  220. //ContextMenu contextmenu = new ContextMenu();
  221. //contextmenu.Tag = grid;
  222. //grid.ContextMenu = contextmenu;
  223. //MenuItem menuItemDelete = new MenuItem();
  224. //menuItemDelete.Header = "删除";
  225. //menuItemDelete.Click += MenuItemDelete_Click;
  226. //MenuItem menuItemInsert = new MenuItem();
  227. //menuItemInsert.Header = "左插入";
  228. //menuItemInsert.Click += MenuItemInsert_Click;
  229. //contextmenu.Items.Add(menuItemDelete);
  230. //contextmenu.Items.Add(menuItemInsert);
  231. List<int> ints = new List<int>();
  232. ints.Add(recipeType.GetProperties().Length);
  233. int k = 0;
  234. recipeStep.LstUnit.ToList().ForEach(x =>
  235. {
  236. Type unitType = x.GetType();
  237. foreach (PropertyInfo propertyInfo in unitType.GetProperties())
  238. {
  239. Binding binding = new Binding()
  240. {
  241. Source = recipeStep.LstUnit[k], // 数据源
  242. //Path = new PropertyPath($"LstUnit[{k}]." + propertyInfo.Name), // 需绑定的数据源属性名
  243. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  244. Mode = BindingMode.TwoWay, // 绑定模式
  245. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  246. };
  247. RowDefinition row1 = new RowDefinition();
  248. grid.RowDefinitions.Add(row1);
  249. var item = propertyInfo.PropertyType.Name;
  250. if (propertyInfo.Name == "UnitName")
  251. {
  252. TextBlock textBlock1 = new TextBlock();
  253. //textBlock1.SetBinding(TextBlock.TextProperty, binding);
  254. textBlock1.Text = propertyInfo.GetValue(x).ToString();
  255. textBlock1.Foreground = Brushes.Red;
  256. //textBlock1.HorizontalAlignment = HorizontalAlignment.Center;
  257. grid.Children.Add(textBlock1);
  258. Grid.SetRow(textBlock1, i);
  259. Grid.SetColumn(textBlock1, grid.ColumnDefinitions.Count - 1);
  260. }
  261. else
  262. {
  263. switch (item)
  264. {
  265. case "Int32":
  266. case "String":
  267. TextBox textBox = new TextBox();
  268. textBox.BorderBrush = Brushes.Transparent;
  269. textBox.SetBinding(TextBox.TextProperty, binding);
  270. grid.Children.Add(textBox);
  271. Grid.SetRow(textBox, i);
  272. Grid.SetColumn(textBox, grid.ColumnDefinitions.Count - 1);
  273. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  274. if (objAttrs.Length > 0)
  275. {
  276. textBox.IsReadOnly = true;
  277. }
  278. break;
  279. case "Boolean":
  280. CheckBox checkBox = new CheckBox();
  281. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  282. grid.Children.Add(checkBox);
  283. Grid.SetRow(checkBox, i);
  284. Grid.SetColumn(checkBox, grid.ColumnDefinitions.Count - 1);
  285. break;
  286. default:
  287. ComboBox comboBox = new ComboBox();
  288. comboBox.BorderBrush = Brushes.Transparent;
  289. //comboBox.Background = Brushes.White;
  290. string path = propertyInfo.Name;
  291. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  292. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  293. grid.Children.Add(comboBox);
  294. Grid.SetRow(comboBox, i);
  295. Grid.SetColumn(comboBox, grid.ColumnDefinitions.Count - 1);
  296. break;
  297. }
  298. }
  299. if (grid.ColumnDefinitions.Count == 2)
  300. {
  301. TextBlock textBlock = new TextBlock();
  302. textBlock.Text = propertyInfo.Name;
  303. grid.Children.Add(textBlock);
  304. Grid.SetRow(textBlock, i);
  305. Grid.SetColumn(textBlock, 0);
  306. }
  307. i++;
  308. }
  309. ints.Add(unitType.GetProperties().Length);
  310. k++;
  311. });
  312. //return new ValueTuple<Grid, List<int>>(grid, ints);
  313. }
  314. /// <summary>
  315. /// step转换为Grid
  316. /// </summary>
  317. /// <param name="recipeStep"></param>
  318. /// <returns></returns>
  319. private ValueTuple<Grid, List<int>> RecipeStepToGrid(RecipeStep recipeStep)
  320. {
  321. Grid grid = new Grid();
  322. ContextMenu contextmenu = new ContextMenu();
  323. contextmenu.Tag = grid;
  324. grid.ContextMenu= contextmenu;
  325. MenuItem menuItemDelete = new MenuItem();
  326. menuItemDelete.Header = "删除";
  327. menuItemDelete.Click += MenuItemDelete_Click;
  328. MenuItem menuItemInsert = new MenuItem();
  329. menuItemInsert.Header = "左插入";
  330. menuItemInsert.Click += MenuItemInsert_Click;
  331. contextmenu.Items.Add(menuItemDelete);
  332. contextmenu.Items.Add(menuItemInsert);
  333. List<int> ints = new List<int>();
  334. ColumnDefinition col1 = new ColumnDefinition();//Key
  335. ColumnDefinition col2 = new ColumnDefinition();//Value
  336. grid.ColumnDefinitions.Add(col1);
  337. grid.ColumnDefinitions.Add(col2);
  338. GridOptions.SetShowBorder(grid, true);
  339. GridOptions.SetLineBrush(grid, Brushes.White);
  340. GridOptions.SetLineThickness(grid, 1);
  341. grid.Margin = new Thickness(15, 5, 0, 0);
  342. Type recipeType = recipeStep.GetType();
  343. int i = 0;
  344. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  345. {
  346. string propertyInfoName = propertyInfo.Name;
  347. string propertyTypeName = propertyInfo.PropertyType.Name;
  348. if (propertyInfoName != "LstUnit")
  349. {
  350. RowDefinition row1 = new RowDefinition();
  351. grid.RowDefinitions.Add(row1);
  352. Binding binding = new Binding()
  353. {
  354. Source = recipeStep, // 数据源
  355. Path = new PropertyPath(propertyInfoName), // 需绑定的数据源属性名
  356. Mode = BindingMode.TwoWay, // 绑定模式
  357. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  358. };
  359. switch (propertyTypeName)
  360. {
  361. case "Int32":
  362. case "String":
  363. TextBox textBox = new TextBox();
  364. textBox.SetBinding(TextBox.TextProperty, binding);
  365. grid.Children.Add(textBox);
  366. Grid.SetRow(textBox, i);
  367. Grid.SetColumn(textBox, 1);
  368. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  369. if (objAttrs.Length > 0)
  370. {
  371. textBox.IsReadOnly = true;
  372. }
  373. break;
  374. case "Boolean":
  375. CheckBox checkBox = new CheckBox();
  376. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  377. grid.Children.Add(checkBox);
  378. Grid.SetRow(checkBox, i);
  379. Grid.SetColumn(checkBox, 1);
  380. break;
  381. default:
  382. ComboBox comboBox = new ComboBox();
  383. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  384. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  385. grid.Children.Add(comboBox);
  386. Grid.SetRow(comboBox, i);
  387. Grid.SetColumn(comboBox, 1);
  388. if (propertyInfo.Name == "PressureUnitMode")
  389. {
  390. comboBox.SelectionChanged += ComboBox_SelectionChanged;
  391. }
  392. break;
  393. }
  394. TextBlock textBlock = new TextBlock();
  395. textBlock.Text = propertyInfoName;
  396. grid.Children.Add(textBlock);
  397. Grid.SetRow(textBlock, i);
  398. Grid.SetColumn(textBlock, 0);
  399. i++;
  400. }
  401. }
  402. ints.Add(recipeType.GetProperties().Length);
  403. int k = 0;
  404. recipeStep.LstUnit.ToList().ForEach(x =>
  405. {
  406. Type unitType = x.GetType();
  407. foreach (PropertyInfo propertyInfo in unitType.GetProperties())
  408. {
  409. Binding binding = new Binding()
  410. {
  411. Source = recipeStep.LstUnit[k], // 数据源
  412. //Path = new PropertyPath($"LstUnit[{k}]." + propertyInfo.Name), // 需绑定的数据源属性名
  413. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  414. Mode = BindingMode.TwoWay, // 绑定模式
  415. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  416. };
  417. RowDefinition row1 = new RowDefinition();
  418. grid.RowDefinitions.Add(row1);
  419. var item = propertyInfo.PropertyType.Name;
  420. if (propertyInfo.Name == "UnitName")
  421. {
  422. TextBlock textBlock1 = new TextBlock();
  423. //textBlock1.SetBinding(TextBlock.TextProperty, binding);
  424. textBlock1.Text = propertyInfo.GetValue(x).ToString();
  425. textBlock1.Foreground = Brushes.Red;
  426. //textBlock1.HorizontalAlignment = HorizontalAlignment.Center;
  427. grid.Children.Add(textBlock1);
  428. Grid.SetRow(textBlock1, i);
  429. Grid.SetColumn(textBlock1, 1);
  430. }
  431. else
  432. {
  433. switch (item)
  434. {
  435. case "Int32":
  436. case "String":
  437. TextBox textBox = new TextBox();
  438. textBox.BorderBrush = Brushes.Transparent;
  439. textBox.SetBinding(TextBox.TextProperty, binding);
  440. grid.Children.Add(textBox);
  441. Grid.SetRow(textBox, i);
  442. Grid.SetColumn(textBox, 1);
  443. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  444. if (objAttrs.Length > 0)
  445. {
  446. textBox.IsReadOnly = true;
  447. }
  448. break;
  449. case "Boolean":
  450. CheckBox checkBox = new CheckBox();
  451. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  452. grid.Children.Add(checkBox);
  453. Grid.SetRow(checkBox, i);
  454. Grid.SetColumn(checkBox, 1);
  455. break;
  456. default:
  457. ComboBox comboBox = new ComboBox();
  458. comboBox.BorderBrush = Brushes.Transparent;
  459. //comboBox.Background = Brushes.White;
  460. string path = propertyInfo.Name;
  461. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  462. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  463. grid.Children.Add(comboBox);
  464. Grid.SetRow(comboBox, i);
  465. Grid.SetColumn(comboBox, 1);
  466. break;
  467. }
  468. }
  469. TextBlock textBlock = new TextBlock();
  470. textBlock.Text = propertyInfo.Name;
  471. grid.Children.Add(textBlock);
  472. Grid.SetRow(textBlock, i);
  473. Grid.SetColumn(textBlock, 0);
  474. i++;
  475. }
  476. ints.Add(unitType.GetProperties().Length);
  477. k++;
  478. });
  479. return new ValueTuple<Grid, List<int>>(grid, ints);
  480. }
  481. private void MenuItemInsert_Click(object sender, RoutedEventArgs e)
  482. {
  483. MenuItem item = sender as MenuItem;
  484. ContextMenu contextMenu = item.Parent as ContextMenu;
  485. Grid grid = contextMenu.Tag as Grid;
  486. int index = GridStackPanel.Children.IndexOf(grid);
  487. RecipeStep recipeStep = new RecipeStep();
  488. recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
  489. recipeStep.LstUnit.Add(new TCPUnit());
  490. recipeStep.LstUnit.Add(new BiasUnit());
  491. recipeStep.LstUnit.Add(new GasControlUnit());
  492. recipeStep.LstUnit.Add(new ESCHVUnit());
  493. recipeStep.LstUnit.Add(new ProcessKitUnit());
  494. CurrentRecipe.Steps.Insert(index , recipeStep);
  495. var item2 = RecipeStepToGrid(recipeStep);
  496. GridStackPanel.Children.Insert(index, item2.Item1);
  497. for (int i = 0; i < CurrentRecipe.Steps.Count; i++)
  498. {
  499. CurrentRecipe.Steps[i].StepNo = i+1;
  500. }
  501. }
  502. private void MenuItemDelete_Click(object sender, RoutedEventArgs e)
  503. {
  504. MenuItem item = sender as MenuItem;
  505. ContextMenu contextMenu = item.Parent as ContextMenu;
  506. Grid grid = contextMenu.Tag as Grid;
  507. int index = GridStackPanel.Children.IndexOf(grid);
  508. GridStackPanel.Children.Remove(grid);
  509. CurrentRecipe.Steps.RemoveAt(index);
  510. for (int i = 0; i < CurrentRecipe.Steps.Count; i++)
  511. {
  512. CurrentRecipe.Steps[i].StepNo = i + 1;
  513. }
  514. }
  515. /// <summary>
  516. /// 获取父控件
  517. /// </summary>
  518. /// <typeparam name="T"></typeparam>
  519. /// <param name="obj"></param>
  520. /// <param name="name"></param>
  521. /// <returns></returns>
  522. public T GetParentObject2<T>(DependencyObject obj, string name) where T : FrameworkElement
  523. {
  524. DependencyObject parent = VisualTreeHelper.GetParent(obj);
  525. while (parent != null)
  526. {
  527. if (parent is T && (((T)parent).Name == name || string.IsNullOrEmpty(name)))
  528. {
  529. return (T)parent;
  530. }
  531. parent = VisualTreeHelper.GetParent(parent);
  532. }
  533. return null;
  534. }
  535. private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
  536. {
  537. if (e.RemovedItems.Count > 0)
  538. {
  539. ComboBox comboBox = sender as ComboBox;
  540. Grid grid = GetParentObject<Grid>(comboBox, "");
  541. int index= GridStackPanel.Children.IndexOf(grid);
  542. RecipeStep recipeStep = CurrentRecipe.Steps[index];
  543. recipeStep.LstUnit.RemoveAt(0);
  544. if (comboBox.SelectedIndex == 0)
  545. {
  546. recipeStep.LstUnit.Insert(0, new PressureByPressureModeUnit());
  547. }
  548. else
  549. {
  550. recipeStep.LstUnit.Insert(0, new PressureByValveModeUnit());
  551. }
  552. GridStackPanel.Children.Remove(grid);
  553. GridStackPanel.Children.Insert(index, RecipeStepToGrid(recipeStep).Item1);
  554. }
  555. }
  556. /// <summary>
  557. /// 获取父控件
  558. /// </summary>
  559. /// <typeparam name="T"></typeparam>
  560. /// <param name="obj"></param>
  561. /// <param name="name"></param>
  562. /// <returns></returns>
  563. public T GetParentObject<T>(DependencyObject obj, string name) where T : FrameworkElement
  564. {
  565. DependencyObject parent = VisualTreeHelper.GetParent(obj);
  566. while (parent != null)
  567. {
  568. if (parent is T && (((T)parent).Name == name || string.IsNullOrEmpty(name)))
  569. {
  570. return (T)parent;
  571. }
  572. parent = VisualTreeHelper.GetParent(parent);
  573. }
  574. return null;
  575. }
  576. private Tuple<DataGrid,List<int>> RecipeStepToDataGrid(RecipeStep recipeStep)
  577. {
  578. DataGrid dataGrid = new DataGrid();
  579. List<int> ints = new List<int>();
  580. DataTable dataTable = new DataTable();
  581. dataTable.Columns.Add("Key");
  582. dataTable.Columns.Add("Value");
  583. dataGrid.CanUserAddRows = false;
  584. dataGrid.AutoGenerateColumns = true;
  585. dataGrid.SelectionUnit = DataGridSelectionUnit.Cell;
  586. dataGrid.SetValue(System.Windows.Controls.VirtualizingStackPanel.IsVirtualizingProperty, false);
  587. Type recipeType = recipeStep.GetType();
  588. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  589. {
  590. if (propertyInfo.Name != "LstUnit")
  591. {
  592. dataTable.Rows.Add(propertyInfo.Name, propertyInfo.GetValue(recipeStep));
  593. }
  594. }
  595. ints.Add(dataTable.Rows.Count);
  596. recipeStep.LstUnit.ToList().ForEach(k =>
  597. {
  598. //List<dynamic> dynamics = new List<dynamic>();
  599. Type type = k.GetType();
  600. ints.Add(type.GetProperties().Length);
  601. foreach (PropertyInfo propertyInfo in type.GetProperties())
  602. {
  603. var name = propertyInfo.Name;
  604. var value = propertyInfo.GetValue(k);
  605. //dynamicModel.PropertyName = name;
  606. //dynamicModel.Property = value;
  607. dataTable.Rows.Add(name, value);
  608. }
  609. });
  610. dataGrid.ItemsSource = dataTable.DefaultView;
  611. //});
  612. return new Tuple<DataGrid, List<int>>(dataGrid, ints);
  613. }
  614. private void ChangeDataGridRowColor(DataGrid dataGrid,List<int> ints)
  615. {
  616. int count = 0;
  617. for (int i = 0; i < ints.Count; i++)
  618. {
  619. for (int j = 0; j < ints[i]; j++)
  620. {
  621. dataGrid.UpdateLayout();
  622. int index = count + j;
  623. DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.Items[index]) as DataGridRow;
  624. row.Background = solidColorBrushes[i];
  625. }
  626. count += ints[i];
  627. }
  628. }
  629. private void ChangeGridRowColor(Grid grid, List<int> ints)
  630. {
  631. int count = 0;
  632. for (int i = 0; i < ints.Count; i++)
  633. {
  634. for (int j = 0; j < ints[i]; j++)
  635. {
  636. //dataGrid.UpdateLayout();
  637. int index = count + j;
  638. //DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.Items[index]) as DataGridRow;
  639. //grid.RowDefinitions[index]
  640. }
  641. count += ints[i];
  642. }
  643. }
  644. #region 旧代码
  645. /// <summary>
  646. /// Open local recipe operation
  647. /// </summary>
  648. /// <param name="recipeDefineFilePath"></param>
  649. //public void OpenLocalRecipe(string recipeVariationName = "")
  650. //{
  651. // var dlg = new OpenFileDialog();
  652. // dlg.DefaultExt = ".rcp";
  653. // dlg.Filter = "Recipe File (.rcp)|*.rcp|All (*.*)|*.*";
  654. // if (dlg.ShowDialog() == true)
  655. // {
  656. // try
  657. // {
  658. // XmlDocument rcpDoc = new XmlDocument();
  659. // rcpDoc.Load(dlg.FileName);
  660. // string recipeVariation = recipeVariationName;
  661. // if (string.IsNullOrEmpty(recipeVariation))
  662. // {
  663. // var root = rcpDoc.SelectSingleNode("/TableRecipeData") as XmlElement;
  664. // recipeVariation = root.Attributes["RecipeVersion"].Value;
  665. // }
  666. // var startupPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
  667. // string dir = System.IO.Path.GetDirectoryName(startupPath);
  668. // List<Aitex.Controls.RecipeCompare.Item> map = CustomXmlSerializer.Deserialize<List<Aitex.Controls.RecipeCompare.Item>>(new System.IO.FileInfo(System.IO.Path.Combine(dir, "map.xml")));
  669. // Func<Aitex.Controls.RecipeCompare.Item, bool> predicate = item => item.Name.Equals(recipeVariation);
  670. // System.IO.FileInfo fi = new System.IO.FileInfo(string.Format("{0}\\config\\{1}.xml", dir, map.Any(predicate) ? map.Single(predicate).No : recipeVariation));
  671. // if (fi.Exists)
  672. // {
  673. // XmlDocument doc = new XmlDocument();
  674. // doc.Load(fi.FullName);
  675. // string formatXml = doc.SelectSingleNode("/Aitex/TableRecipeFormat").OuterXml;
  676. // string recipeXml = rcpDoc.SelectSingleNode("/TableRecipeData").OuterXml;
  677. // //LoadRecipe(formatXml, recipeXml);
  678. // if (OnLocalRecipeOpened != null)
  679. // OnLocalRecipeOpened.Invoke(new Tuple<string, string>(recipeVariation, dlg.FileName), null);
  680. // }
  681. // else
  682. // {
  683. // MessageBox.Show(string.Format("工艺程序版本{0}的描述文件不存在,无法正确识别该版本的工艺程序文件。", recipeVariation), "工艺程序打开失败",
  684. // MessageBoxButton.OK, MessageBoxImage.Error);
  685. // }
  686. // }
  687. // catch (Exception ex)
  688. // {
  689. // System.Diagnostics.Debug.WriteLine(ex.Message);
  690. // MessageBox.Show(string.Format("open recipe {0} failed,please confirm the recipe file is exist and valid。\r\n{1}", dlg.FileName, ex.Message), "Open recipe failed",
  691. // MessageBoxButton.OK, MessageBoxImage.Error);
  692. // }
  693. // }
  694. //}
  695. /// <summary>
  696. /// Save recipe file
  697. /// </summary>
  698. //private void SaveRecipeFile()
  699. //{
  700. // //try
  701. // //{
  702. // // if (Errors != null && Errors.Count > 0)
  703. // // {
  704. // // var ret = MessageBox.Show(string.Format("Recipe have {0} error,continue save?", Errors.Count), "Save", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
  705. // // if (ret != MessageBoxResult.Yes)
  706. // // return;
  707. // // }
  708. // // if (OnSaveRecipeFile != null)
  709. // // {
  710. // // IsRecipeModified = false;
  711. // // }
  712. // //}
  713. // //catch (Exception ex)
  714. // //{
  715. // // System.Diagnostics.Debug.WriteLine(ex.Message);
  716. // // MessageBox.Show("save recipe failed!\r\n\r\n" + ex.Message, "Save", MessageBoxButton.OK, MessageBoxImage.Warning);
  717. // //}
  718. //}
  719. /// <summary>
  720. /// calc recipe total time
  721. /// </summary>
  722. private void CalcRecipeTime()
  723. {
  724. //int timeStepRowId = -1;
  725. //int loopStepRowId = -1;
  726. //for (int i = 0; i < RecipeRows.Count; i++)
  727. //{
  728. // if (RecipeRows[i].TechnicalName == "Time")
  729. // timeStepRowId = i;
  730. // if (RecipeRows[i].TechnicalName == "Loop")
  731. // loopStepRowId = i;
  732. // if (loopStepRowId != -1 && timeStepRowId != -1)
  733. // break;
  734. //}
  735. //TimeSpan tspan = new TimeSpan();
  736. //for (int stepNo = 0; stepNo < RecipeRows[timeStepRowId].RecipeItems.Count; stepNo++)
  737. //{
  738. // string loopStr = RecipeRows[loopStepRowId].RecipeItems[stepNo].Value;
  739. // bool isLoopStart = Regex.IsMatch(loopStr, @"^Loop\x20\d+$");
  740. // if (isLoopStart)
  741. // {
  742. // int loopNum = int.Parse(loopStr.ToLower().Replace("loop", "").Replace(" ", ""));
  743. // TimeSpan ts = new TimeSpan();
  744. // for (int innerStepNo = stepNo; innerStepNo < RecipeRows[timeStepRowId].RecipeItems.Count; innerStepNo++)
  745. // {
  746. // loopStr = RecipeRows[loopStepRowId].RecipeItems[innerStepNo].Value;
  747. // stepNo = innerStepNo;
  748. // string timeDuration = RecipeRows[timeStepRowId].RecipeItems[innerStepNo].Value;
  749. // string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
  750. // if (timeArr.Length == 3)
  751. // {
  752. // int h, mi, s;
  753. // if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
  754. // {
  755. // var tt = new TimeSpan(h, mi, s);
  756. // ts += tt;
  757. // }
  758. // }
  759. // bool isLoopEnd = Regex.IsMatch(loopStr, @"^Loop End$");
  760. // if (isLoopEnd)
  761. // {
  762. // tspan += new TimeSpan(ts.Ticks * loopNum);
  763. // break;
  764. // }
  765. // }
  766. // }
  767. // else
  768. // {
  769. // string timeDuration = RecipeRows[timeStepRowId].RecipeItems[stepNo].Value;
  770. // string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
  771. // if (timeArr.Length == 3)
  772. // {
  773. // int h, mi, s;
  774. // if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
  775. // {
  776. // var ts = new TimeSpan(h, mi, s);
  777. // tspan += ts;
  778. // }
  779. // }
  780. // }
  781. //}
  782. //RecipeInfo = string.Format("共{0}步,总时间{1}:{2}:{3}", RecipeRows[0].RecipeItems.Count, (int)tspan.TotalHours, tspan.Minutes.ToString("00"), tspan.Seconds.ToString("00"));
  783. //InvokePropertyChanged("RecipeInfo");
  784. }
  785. #region INotifyPropertyChanged
  786. public event PropertyChangedEventHandler PropertyChanged;
  787. public void InvokePropertyChanged(string propertyName)
  788. {
  789. if (PropertyChanged != null)
  790. {
  791. PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
  792. }
  793. }
  794. #endregion INotifyPropertyChanged
  795. }
  796. //public class RecipeRow
  797. //{
  798. // //private ObservableCollection<SmartCellData> _recipeItems = new ObservableCollection<SmartCellData>();
  799. // //public RecipeRow(params SmartCellData[] vars)
  800. // //{
  801. // // foreach (var var in vars)
  802. // // _recipeItems.Add(var);
  803. // //}
  804. // //public string CatalogName { get; set; }
  805. // //public string FriendlyName { get; set; }
  806. // //public string TechnicalName { get; set; }
  807. // //public ObservableCollection<SmartCellData> RecipeItems
  808. // //{
  809. // // get { return _recipeItems; }
  810. // // set { _recipeItems = value; }
  811. // //}
  812. //}
  813. ///// <summary>
  814. ///// Recipe head
  815. ///// </summary>
  816. //public class RecipeHead
  817. //{
  818. // //public string RecipeVariation { get; set; }
  819. // //public string CreationTime { get; set; }
  820. // //public string LastRevisionTime { get; set; }
  821. // //public string CreatedBy { get; set; }
  822. // //public string LastModifiedBy { get; set; }
  823. // //public string PressureMode { get; set; }
  824. // //public string Description { get; set; }
  825. // //public string BasePressure
  826. // //{
  827. // // get; set;
  828. // //}
  829. // //public string PumpDownLimit
  830. // //{
  831. // // get; set;
  832. // //}
  833. // //public string PurgeActive
  834. // //{
  835. // // get; set;
  836. // //}
  837. // //public string NotToPurgeOrVent
  838. // //{
  839. // // get; set;
  840. // //}
  841. // //public string Barcode
  842. // //{
  843. // // get; set;
  844. // //}
  845. // //public string SubstrateTemp
  846. // //{
  847. // // get; set;
  848. // //}
  849. // //public string PumpingPinState
  850. // //{
  851. // // get; set;
  852. // //}
  853. // //public string VentingPinState
  854. // //{
  855. // // get; set;
  856. // //}
  857. // //public string PinDownPressure
  858. // //{
  859. // // get; set;
  860. // //}
  861. //}
  862. //public class EndPointConfigItem : INotifyPropertyChanged
  863. //{
  864. // public event PropertyChangedEventHandler PropertyChanged;
  865. // public void InvokePropertyChanged(string propertyName)
  866. // {
  867. // if (PropertyChanged != null)
  868. // {
  869. // PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
  870. // }
  871. // }
  872. // //public string ExposureTime { get; set; }
  873. // //public string WaveLengthA { get; set; }
  874. // //public string BinningA { get; set; }
  875. // //public string WaveLengthB { get; set; }
  876. // //public string BinningB { get; set; }
  877. // //public string WaveLengthC { get; set; }
  878. // //public string BinningC { get; set; }
  879. // //public string WaveLengthD { get; set; }
  880. // //public string BinningD { get; set; }
  881. // //public string Fd { get; set; }
  882. // //public string PrefilterTime { get; set; }
  883. // //public string PostfilterTime { get; set; }
  884. // //public string AlgorithmType { get; set; }
  885. // //public string Criteria { get; set; }
  886. // //public string DelayTime { get; set; }
  887. // //public string ValidationTime { get; set; }
  888. // //public string ValidationValue { get; set; }
  889. // //public string TimeWindow { get; set; }
  890. // //public string MinimalTime { get; set; }
  891. // //public string PostponeTime { get; set; }
  892. // //public bool Control { get; set; }
  893. // //public bool Normalization { get; set; }
  894. // //public bool EnablePostponePercent { get; set; }
  895. // //public bool EnableCriterialPercent { get; set; }
  896. // //public bool EnableEventTrigger { get; set; }
  897. // //public bool IsFaultIfNoTrigger { get; set; }
  898. // //public string ToValue()
  899. // //{
  900. // // return
  901. // // $@"ExposureTime={ExposureTime};WaveLengthA={WaveLengthA};BinningA={BinningA};WaveLengthB={WaveLengthB};" +
  902. // // $@"BinningB={BinningB};WaveLengthC={WaveLengthC};BinningC={BinningC};WaveLengthD={WaveLengthD};BinningD={BinningD};Fd={Fd};" +
  903. // // $@"PrefilterTime={PrefilterTime};PostfilterTime={PostfilterTime};AlgorithmType={AlgorithmType};Criteria={Criteria};DelayTime={DelayTime};ValidationTime={ValidationTime};" +
  904. // // $@"ValidationValue={ValidationValue};TimeWindow={TimeWindow};MinimalTime={MinimalTime};PostponeTime={PostponeTime};Control={Control};Normalization={Normalization};" +
  905. // // $@"EnablePostponePercent={EnablePostponePercent};EnableCriterialPercent={EnableCriterialPercent};EnableEventTrigger={EnableEventTrigger};IsFaultIfNoTrigger={IsFaultIfNoTrigger};"
  906. // // ;
  907. // //}
  908. // //public void SetValue(string config)
  909. // //{
  910. // // if (string.IsNullOrEmpty(config))
  911. // // return;
  912. // // string[] items = config.Split(';');
  913. // // foreach (var item in items)
  914. // // {
  915. // // if (string.IsNullOrEmpty(item))
  916. // // continue;
  917. // // string[] pairs = item.Split('=');
  918. // // if (pairs.Length != 2)
  919. // // continue;
  920. // // Parallel.ForEach(this.GetType().GetProperties(),
  921. // // property =>
  922. // // {
  923. // // PropertyInfo pi = (PropertyInfo) property;
  924. // // if (pi.Name == pairs[0])
  925. // // {
  926. // // try
  927. // // {
  928. // // var convertedValue = Convert.ChangeType(pairs[1], pi.PropertyType);
  929. // // var originValue = Convert.ChangeType(pi.GetValue(this, null), pi.PropertyType);
  930. // // if (originValue != convertedValue)
  931. // // {
  932. // // pi.SetValue(this, convertedValue, null);
  933. // // }
  934. // // }
  935. // // catch (Exception)
  936. // // {
  937. // // }
  938. // // }
  939. // // });
  940. // // }
  941. // //}
  942. //}
  943. #endregion
  944. }