RecipeEditorControlViewModel.cs 46 KB

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