RecipeEditorControlViewModel.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  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. public RecipeEditorControlViewModel()
  28. {
  29. //solidColorBrushes.Add(new SolidColorBrush(Colors.Aqua));
  30. //solidColorBrushes.Add(new SolidColorBrush(Colors.Aquamarine));
  31. //solidColorBrushes.Add(new SolidColorBrush(Colors.LawnGreen));
  32. //solidColorBrushes.Add(new SolidColorBrush(Colors.LightYellow));
  33. //solidColorBrushes.Add(new SolidColorBrush(Colors.DarkOrange));
  34. //solidColorBrushes.Add(new SolidColorBrush(Colors.MistyRose));
  35. //solidColorBrushes.Add(new SolidColorBrush(Colors.BurlyWood));
  36. //solidColorBrushes.Add(new SolidColorBrush(Colors.Gainsboro));
  37. //solidColorBrushes.Add(new SolidColorBrush(Colors.Beige));
  38. //solidColorBrushes.Add(new SolidColorBrush(Colors.Yellow));
  39. //solidColorBrushes.Add(new SolidColorBrush(Colors.Magenta));
  40. }
  41. public void OnAddStep()
  42. {
  43. if (CurrentRecipe != null)
  44. {
  45. RecipeStep recipeStep = new RecipeStep();
  46. recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
  47. recipeStep.LstUnit.Add(new TCPUnit());
  48. recipeStep.LstUnit.Add(new BiasUnit());
  49. recipeStep.LstUnit.Add(new GasControlUnit());
  50. recipeStep.LstUnit.Add(new ESCHVUnit());
  51. recipeStep.LstUnit.Add(new ProcessKitUnit());
  52. recipeStep.StepNo = GridStackPanel.Children.Count;
  53. CurrentRecipe.Steps.Add(recipeStep);
  54. var item = RecipeStepToGrid(recipeStep);
  55. GridStackPanel.Children.Add(item.Item1);
  56. }
  57. }
  58. public void OnDeleteStep()
  59. {
  60. if (CurrentRecipe != null&& CurrentRecipe.Steps.Count>0)
  61. {
  62. CurrentRecipe.Steps.RemoveAt(CurrentRecipe.Steps.Count - 1);
  63. GridStackPanel.Children.RemoveAt(GridStackPanel.Children.Count - 1);
  64. }
  65. }
  66. /// <summary>
  67. /// 选中recipe,显示界面
  68. /// </summary>
  69. /// <param name="recipe"></param>
  70. public void LoadRecipe(Recipe recipe)
  71. {
  72. GridStackPanel.Children.Clear();
  73. CurrentRecipe = null;
  74. GC.Collect(); // This should pick up the control removed at a previous MouseDown
  75. GC.WaitForPendingFinalizers(); // Doesn't help either
  76. GC.Collect();
  77. GC.WaitForPendingFinalizers(); // Doesn't help either
  78. CurrentRecipe = recipe;
  79. recipe.Steps.ToList().ForEach(x =>
  80. {
  81. var tupleValue = RecipeStepToGrid(x);
  82. GridStackPanel.Children.Add(tupleValue.Item1);
  83. });
  84. LoadHeadWrapPanel(recipe);
  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. /// <summary>
  153. /// step转换为Grid
  154. /// </summary>
  155. /// <param name="recipeStep"></param>
  156. /// <returns></returns>
  157. private ValueTuple<Grid, List<int>> RecipeStepToGrid(RecipeStep recipeStep)
  158. {
  159. Grid grid = new Grid();
  160. List<int> ints = new List<int>();
  161. ColumnDefinition col1 = new ColumnDefinition();//Key
  162. ColumnDefinition col2 = new ColumnDefinition();//Value
  163. grid.ColumnDefinitions.Add(col1);
  164. grid.ColumnDefinitions.Add(col2);
  165. GridOptions.SetShowBorder(grid, true);
  166. GridOptions.SetLineBrush(grid, Brushes.White);
  167. GridOptions.SetLineThickness(grid, 1);
  168. grid.Margin = new Thickness(15, 5, 0, 0);
  169. Type recipeType = recipeStep.GetType();
  170. int i = 0;
  171. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  172. {
  173. string propertyInfoName = propertyInfo.Name;
  174. string propertyTypeName = propertyInfo.PropertyType.Name;
  175. if (propertyInfoName != "LstUnit")
  176. {
  177. RowDefinition row1 = new RowDefinition();
  178. grid.RowDefinitions.Add(row1);
  179. Binding binding = new Binding()
  180. {
  181. Source = recipeStep, // 数据源
  182. Path = new PropertyPath(propertyInfoName), // 需绑定的数据源属性名
  183. Mode = BindingMode.TwoWay, // 绑定模式
  184. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  185. };
  186. switch (propertyTypeName)
  187. {
  188. case "Int32":
  189. case "String":
  190. TextBox textBox = new TextBox();
  191. textBox.SetBinding(TextBox.TextProperty, binding);
  192. grid.Children.Add(textBox);
  193. Grid.SetRow(textBox, i);
  194. Grid.SetColumn(textBox, 1);
  195. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  196. if (objAttrs.Length > 0)
  197. {
  198. textBox.IsReadOnly = true;
  199. }
  200. break;
  201. case "Boolean":
  202. CheckBox checkBox = new CheckBox();
  203. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  204. grid.Children.Add(checkBox);
  205. Grid.SetRow(checkBox, i);
  206. Grid.SetColumn(checkBox, 1);
  207. break;
  208. default:
  209. ComboBox comboBox = new ComboBox();
  210. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  211. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  212. grid.Children.Add(comboBox);
  213. Grid.SetRow(comboBox, i);
  214. Grid.SetColumn(comboBox, 1);
  215. if (propertyInfo.Name == "PressureUnitMode")
  216. {
  217. comboBox.SelectionChanged += ComboBox_SelectionChanged;
  218. }
  219. break;
  220. }
  221. TextBlock textBlock = new TextBlock();
  222. textBlock.Text = propertyInfoName;
  223. grid.Children.Add(textBlock);
  224. Grid.SetRow(textBlock, i);
  225. Grid.SetColumn(textBlock, 0);
  226. i++;
  227. }
  228. }
  229. ints.Add(recipeType.GetProperties().Length);
  230. int k = 0;
  231. recipeStep.LstUnit.ToList().ForEach(x =>
  232. {
  233. Type unitType = x.GetType();
  234. foreach (PropertyInfo propertyInfo in unitType.GetProperties())
  235. {
  236. Binding binding = new Binding()
  237. {
  238. Source = recipeStep.LstUnit[k], // 数据源
  239. //Path = new PropertyPath($"LstUnit[{k}]." + propertyInfo.Name), // 需绑定的数据源属性名
  240. Path = new PropertyPath(propertyInfo.Name), // 需绑定的数据源属性名
  241. Mode = BindingMode.TwoWay, // 绑定模式
  242. UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
  243. };
  244. RowDefinition row1 = new RowDefinition();
  245. grid.RowDefinitions.Add(row1);
  246. var item = propertyInfo.PropertyType.Name;
  247. if (propertyInfo.Name == "UnitName")
  248. {
  249. TextBlock textBlock1 = new TextBlock();
  250. //textBlock1.SetBinding(TextBlock.TextProperty, binding);
  251. textBlock1.Text = propertyInfo.GetValue(x).ToString();
  252. textBlock1.Foreground = Brushes.Red;
  253. //textBlock1.HorizontalAlignment = HorizontalAlignment.Center;
  254. grid.Children.Add(textBlock1);
  255. Grid.SetRow(textBlock1, i);
  256. Grid.SetColumn(textBlock1, 1);
  257. }
  258. else
  259. {
  260. switch (item)
  261. {
  262. case "Int32":
  263. case "String":
  264. TextBox textBox = new TextBox();
  265. textBox.BorderBrush = Brushes.Transparent;
  266. textBox.SetBinding(TextBox.TextProperty, binding);
  267. grid.Children.Add(textBox);
  268. Grid.SetRow(textBox, i);
  269. Grid.SetColumn(textBox, 1);
  270. object[] objAttrs = propertyInfo.GetCustomAttributes(typeof(IsOnlyReadAttribute), true);
  271. if (objAttrs.Length > 0)
  272. {
  273. textBox.IsReadOnly = true;
  274. }
  275. break;
  276. case "Boolean":
  277. CheckBox checkBox = new CheckBox();
  278. checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
  279. grid.Children.Add(checkBox);
  280. Grid.SetRow(checkBox, i);
  281. Grid.SetColumn(checkBox, 1);
  282. break;
  283. default:
  284. ComboBox comboBox = new ComboBox();
  285. comboBox.BorderBrush = Brushes.Transparent;
  286. //comboBox.Background = Brushes.White;
  287. string path = propertyInfo.Name;
  288. comboBox.SetBinding(ComboBox.SelectedItemProperty, binding);
  289. ItemsControlHelper.SetEnumValuesToItemsSource(comboBox, true);
  290. grid.Children.Add(comboBox);
  291. Grid.SetRow(comboBox, i);
  292. Grid.SetColumn(comboBox, 1);
  293. break;
  294. }
  295. }
  296. TextBlock textBlock = new TextBlock();
  297. textBlock.Text = propertyInfo.Name;
  298. grid.Children.Add(textBlock);
  299. Grid.SetRow(textBlock, i);
  300. Grid.SetColumn(textBlock, 0);
  301. i++;
  302. }
  303. ints.Add(unitType.GetProperties().Length);
  304. k++;
  305. });
  306. return new ValueTuple<Grid, List<int>>(grid, ints);
  307. }
  308. private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
  309. {
  310. if (e.RemovedItems.Count > 0)
  311. {
  312. ComboBox comboBox = sender as ComboBox;
  313. Grid grid = GetParentObject<Grid>(comboBox, "");
  314. int index= GridStackPanel.Children.IndexOf(grid);
  315. RecipeStep recipeStep = CurrentRecipe.Steps[index];
  316. recipeStep.LstUnit.RemoveAt(0);
  317. if (comboBox.SelectedIndex == 0)
  318. {
  319. recipeStep.LstUnit.Insert(0, new PressureByPressureModeUnit());
  320. }
  321. else
  322. {
  323. recipeStep.LstUnit.Insert(0, new PressureByValveModeUnit());
  324. }
  325. GridStackPanel.Children.Remove(grid);
  326. GridStackPanel.Children.Insert(index, RecipeStepToGrid(recipeStep).Item1);
  327. }
  328. }
  329. /// <summary>
  330. /// 获取父控件
  331. /// </summary>
  332. /// <typeparam name="T"></typeparam>
  333. /// <param name="obj"></param>
  334. /// <param name="name"></param>
  335. /// <returns></returns>
  336. public T GetParentObject<T>(DependencyObject obj, string name) where T : FrameworkElement
  337. {
  338. DependencyObject parent = VisualTreeHelper.GetParent(obj);
  339. while (parent != null)
  340. {
  341. if (parent is T && (((T)parent).Name == name || string.IsNullOrEmpty(name)))
  342. {
  343. return (T)parent;
  344. }
  345. parent = VisualTreeHelper.GetParent(parent);
  346. }
  347. return null;
  348. }
  349. private Tuple<DataGrid,List<int>> RecipeStepToDataGrid(RecipeStep recipeStep)
  350. {
  351. DataGrid dataGrid = new DataGrid();
  352. List<int> ints = new List<int>();
  353. DataTable dataTable = new DataTable();
  354. dataTable.Columns.Add("Key");
  355. dataTable.Columns.Add("Value");
  356. dataGrid.CanUserAddRows = false;
  357. dataGrid.AutoGenerateColumns = true;
  358. dataGrid.SelectionUnit = DataGridSelectionUnit.Cell;
  359. dataGrid.SetValue(System.Windows.Controls.VirtualizingStackPanel.IsVirtualizingProperty, false);
  360. Type recipeType = recipeStep.GetType();
  361. foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
  362. {
  363. if (propertyInfo.Name != "LstUnit")
  364. {
  365. dataTable.Rows.Add(propertyInfo.Name, propertyInfo.GetValue(recipeStep));
  366. }
  367. }
  368. ints.Add(dataTable.Rows.Count);
  369. recipeStep.LstUnit.ToList().ForEach(k =>
  370. {
  371. //List<dynamic> dynamics = new List<dynamic>();
  372. Type type = k.GetType();
  373. ints.Add(type.GetProperties().Length);
  374. foreach (PropertyInfo propertyInfo in type.GetProperties())
  375. {
  376. var name = propertyInfo.Name;
  377. var value = propertyInfo.GetValue(k);
  378. //dynamicModel.PropertyName = name;
  379. //dynamicModel.Property = value;
  380. dataTable.Rows.Add(name, value);
  381. }
  382. });
  383. dataGrid.ItemsSource = dataTable.DefaultView;
  384. //});
  385. return new Tuple<DataGrid, List<int>>(dataGrid, ints);
  386. }
  387. private void ChangeDataGridRowColor(DataGrid dataGrid,List<int> ints)
  388. {
  389. int count = 0;
  390. for (int i = 0; i < ints.Count; i++)
  391. {
  392. for (int j = 0; j < ints[i]; j++)
  393. {
  394. dataGrid.UpdateLayout();
  395. int index = count + j;
  396. DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.Items[index]) as DataGridRow;
  397. row.Background = solidColorBrushes[i];
  398. }
  399. count += ints[i];
  400. }
  401. }
  402. private void ChangeGridRowColor(Grid grid, List<int> ints)
  403. {
  404. int count = 0;
  405. for (int i = 0; i < ints.Count; i++)
  406. {
  407. for (int j = 0; j < ints[i]; j++)
  408. {
  409. //dataGrid.UpdateLayout();
  410. int index = count + j;
  411. //DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.Items[index]) as DataGridRow;
  412. //grid.RowDefinitions[index]
  413. }
  414. count += ints[i];
  415. }
  416. }
  417. #region 旧代码
  418. /// <summary>
  419. /// Open local recipe operation
  420. /// </summary>
  421. /// <param name="recipeDefineFilePath"></param>
  422. //public void OpenLocalRecipe(string recipeVariationName = "")
  423. //{
  424. // var dlg = new OpenFileDialog();
  425. // dlg.DefaultExt = ".rcp";
  426. // dlg.Filter = "Recipe File (.rcp)|*.rcp|All (*.*)|*.*";
  427. // if (dlg.ShowDialog() == true)
  428. // {
  429. // try
  430. // {
  431. // XmlDocument rcpDoc = new XmlDocument();
  432. // rcpDoc.Load(dlg.FileName);
  433. // string recipeVariation = recipeVariationName;
  434. // if (string.IsNullOrEmpty(recipeVariation))
  435. // {
  436. // var root = rcpDoc.SelectSingleNode("/TableRecipeData") as XmlElement;
  437. // recipeVariation = root.Attributes["RecipeVersion"].Value;
  438. // }
  439. // var startupPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
  440. // string dir = System.IO.Path.GetDirectoryName(startupPath);
  441. // List<Aitex.Controls.RecipeCompare.Item> map = CustomXmlSerializer.Deserialize<List<Aitex.Controls.RecipeCompare.Item>>(new System.IO.FileInfo(System.IO.Path.Combine(dir, "map.xml")));
  442. // Func<Aitex.Controls.RecipeCompare.Item, bool> predicate = item => item.Name.Equals(recipeVariation);
  443. // System.IO.FileInfo fi = new System.IO.FileInfo(string.Format("{0}\\config\\{1}.xml", dir, map.Any(predicate) ? map.Single(predicate).No : recipeVariation));
  444. // if (fi.Exists)
  445. // {
  446. // XmlDocument doc = new XmlDocument();
  447. // doc.Load(fi.FullName);
  448. // string formatXml = doc.SelectSingleNode("/Aitex/TableRecipeFormat").OuterXml;
  449. // string recipeXml = rcpDoc.SelectSingleNode("/TableRecipeData").OuterXml;
  450. // //LoadRecipe(formatXml, recipeXml);
  451. // if (OnLocalRecipeOpened != null)
  452. // OnLocalRecipeOpened.Invoke(new Tuple<string, string>(recipeVariation, dlg.FileName), null);
  453. // }
  454. // else
  455. // {
  456. // MessageBox.Show(string.Format("工艺程序版本{0}的描述文件不存在,无法正确识别该版本的工艺程序文件。", recipeVariation), "工艺程序打开失败",
  457. // MessageBoxButton.OK, MessageBoxImage.Error);
  458. // }
  459. // }
  460. // catch (Exception ex)
  461. // {
  462. // System.Diagnostics.Debug.WriteLine(ex.Message);
  463. // 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",
  464. // MessageBoxButton.OK, MessageBoxImage.Error);
  465. // }
  466. // }
  467. //}
  468. /// <summary>
  469. /// Save recipe file
  470. /// </summary>
  471. //private void SaveRecipeFile()
  472. //{
  473. // //try
  474. // //{
  475. // // if (Errors != null && Errors.Count > 0)
  476. // // {
  477. // // var ret = MessageBox.Show(string.Format("Recipe have {0} error,continue save?", Errors.Count), "Save", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
  478. // // if (ret != MessageBoxResult.Yes)
  479. // // return;
  480. // // }
  481. // // if (OnSaveRecipeFile != null)
  482. // // {
  483. // // IsRecipeModified = false;
  484. // // }
  485. // //}
  486. // //catch (Exception ex)
  487. // //{
  488. // // System.Diagnostics.Debug.WriteLine(ex.Message);
  489. // // MessageBox.Show("save recipe failed!\r\n\r\n" + ex.Message, "Save", MessageBoxButton.OK, MessageBoxImage.Warning);
  490. // //}
  491. //}
  492. /// <summary>
  493. /// calc recipe total time
  494. /// </summary>
  495. private void CalcRecipeTime()
  496. {
  497. //int timeStepRowId = -1;
  498. //int loopStepRowId = -1;
  499. //for (int i = 0; i < RecipeRows.Count; i++)
  500. //{
  501. // if (RecipeRows[i].TechnicalName == "Time")
  502. // timeStepRowId = i;
  503. // if (RecipeRows[i].TechnicalName == "Loop")
  504. // loopStepRowId = i;
  505. // if (loopStepRowId != -1 && timeStepRowId != -1)
  506. // break;
  507. //}
  508. //TimeSpan tspan = new TimeSpan();
  509. //for (int stepNo = 0; stepNo < RecipeRows[timeStepRowId].RecipeItems.Count; stepNo++)
  510. //{
  511. // string loopStr = RecipeRows[loopStepRowId].RecipeItems[stepNo].Value;
  512. // bool isLoopStart = Regex.IsMatch(loopStr, @"^Loop\x20\d+$");
  513. // if (isLoopStart)
  514. // {
  515. // int loopNum = int.Parse(loopStr.ToLower().Replace("loop", "").Replace(" ", ""));
  516. // TimeSpan ts = new TimeSpan();
  517. // for (int innerStepNo = stepNo; innerStepNo < RecipeRows[timeStepRowId].RecipeItems.Count; innerStepNo++)
  518. // {
  519. // loopStr = RecipeRows[loopStepRowId].RecipeItems[innerStepNo].Value;
  520. // stepNo = innerStepNo;
  521. // string timeDuration = RecipeRows[timeStepRowId].RecipeItems[innerStepNo].Value;
  522. // string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
  523. // if (timeArr.Length == 3)
  524. // {
  525. // int h, mi, s;
  526. // if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
  527. // {
  528. // var tt = new TimeSpan(h, mi, s);
  529. // ts += tt;
  530. // }
  531. // }
  532. // bool isLoopEnd = Regex.IsMatch(loopStr, @"^Loop End$");
  533. // if (isLoopEnd)
  534. // {
  535. // tspan += new TimeSpan(ts.Ticks * loopNum);
  536. // break;
  537. // }
  538. // }
  539. // }
  540. // else
  541. // {
  542. // string timeDuration = RecipeRows[timeStepRowId].RecipeItems[stepNo].Value;
  543. // string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
  544. // if (timeArr.Length == 3)
  545. // {
  546. // int h, mi, s;
  547. // if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
  548. // {
  549. // var ts = new TimeSpan(h, mi, s);
  550. // tspan += ts;
  551. // }
  552. // }
  553. // }
  554. //}
  555. //RecipeInfo = string.Format("共{0}步,总时间{1}:{2}:{3}", RecipeRows[0].RecipeItems.Count, (int)tspan.TotalHours, tspan.Minutes.ToString("00"), tspan.Seconds.ToString("00"));
  556. //InvokePropertyChanged("RecipeInfo");
  557. }
  558. #region INotifyPropertyChanged
  559. public event PropertyChangedEventHandler PropertyChanged;
  560. public void InvokePropertyChanged(string propertyName)
  561. {
  562. if (PropertyChanged != null)
  563. {
  564. PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
  565. }
  566. }
  567. #endregion INotifyPropertyChanged
  568. }
  569. //public class RecipeRow
  570. //{
  571. // //private ObservableCollection<SmartCellData> _recipeItems = new ObservableCollection<SmartCellData>();
  572. // //public RecipeRow(params SmartCellData[] vars)
  573. // //{
  574. // // foreach (var var in vars)
  575. // // _recipeItems.Add(var);
  576. // //}
  577. // //public string CatalogName { get; set; }
  578. // //public string FriendlyName { get; set; }
  579. // //public string TechnicalName { get; set; }
  580. // //public ObservableCollection<SmartCellData> RecipeItems
  581. // //{
  582. // // get { return _recipeItems; }
  583. // // set { _recipeItems = value; }
  584. // //}
  585. //}
  586. ///// <summary>
  587. ///// Recipe head
  588. ///// </summary>
  589. //public class RecipeHead
  590. //{
  591. // //public string RecipeVariation { get; set; }
  592. // //public string CreationTime { get; set; }
  593. // //public string LastRevisionTime { get; set; }
  594. // //public string CreatedBy { get; set; }
  595. // //public string LastModifiedBy { get; set; }
  596. // //public string PressureMode { get; set; }
  597. // //public string Description { get; set; }
  598. // //public string BasePressure
  599. // //{
  600. // // get; set;
  601. // //}
  602. // //public string PumpDownLimit
  603. // //{
  604. // // get; set;
  605. // //}
  606. // //public string PurgeActive
  607. // //{
  608. // // get; set;
  609. // //}
  610. // //public string NotToPurgeOrVent
  611. // //{
  612. // // get; set;
  613. // //}
  614. // //public string Barcode
  615. // //{
  616. // // get; set;
  617. // //}
  618. // //public string SubstrateTemp
  619. // //{
  620. // // get; set;
  621. // //}
  622. // //public string PumpingPinState
  623. // //{
  624. // // get; set;
  625. // //}
  626. // //public string VentingPinState
  627. // //{
  628. // // get; set;
  629. // //}
  630. // //public string PinDownPressure
  631. // //{
  632. // // get; set;
  633. // //}
  634. //}
  635. //public class EndPointConfigItem : INotifyPropertyChanged
  636. //{
  637. // public event PropertyChangedEventHandler PropertyChanged;
  638. // public void InvokePropertyChanged(string propertyName)
  639. // {
  640. // if (PropertyChanged != null)
  641. // {
  642. // PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
  643. // }
  644. // }
  645. // //public string ExposureTime { get; set; }
  646. // //public string WaveLengthA { get; set; }
  647. // //public string BinningA { get; set; }
  648. // //public string WaveLengthB { get; set; }
  649. // //public string BinningB { get; set; }
  650. // //public string WaveLengthC { get; set; }
  651. // //public string BinningC { get; set; }
  652. // //public string WaveLengthD { get; set; }
  653. // //public string BinningD { get; set; }
  654. // //public string Fd { get; set; }
  655. // //public string PrefilterTime { get; set; }
  656. // //public string PostfilterTime { get; set; }
  657. // //public string AlgorithmType { get; set; }
  658. // //public string Criteria { get; set; }
  659. // //public string DelayTime { get; set; }
  660. // //public string ValidationTime { get; set; }
  661. // //public string ValidationValue { get; set; }
  662. // //public string TimeWindow { get; set; }
  663. // //public string MinimalTime { get; set; }
  664. // //public string PostponeTime { get; set; }
  665. // //public bool Control { get; set; }
  666. // //public bool Normalization { get; set; }
  667. // //public bool EnablePostponePercent { get; set; }
  668. // //public bool EnableCriterialPercent { get; set; }
  669. // //public bool EnableEventTrigger { get; set; }
  670. // //public bool IsFaultIfNoTrigger { get; set; }
  671. // //public string ToValue()
  672. // //{
  673. // // return
  674. // // $@"ExposureTime={ExposureTime};WaveLengthA={WaveLengthA};BinningA={BinningA};WaveLengthB={WaveLengthB};" +
  675. // // $@"BinningB={BinningB};WaveLengthC={WaveLengthC};BinningC={BinningC};WaveLengthD={WaveLengthD};BinningD={BinningD};Fd={Fd};" +
  676. // // $@"PrefilterTime={PrefilterTime};PostfilterTime={PostfilterTime};AlgorithmType={AlgorithmType};Criteria={Criteria};DelayTime={DelayTime};ValidationTime={ValidationTime};" +
  677. // // $@"ValidationValue={ValidationValue};TimeWindow={TimeWindow};MinimalTime={MinimalTime};PostponeTime={PostponeTime};Control={Control};Normalization={Normalization};" +
  678. // // $@"EnablePostponePercent={EnablePostponePercent};EnableCriterialPercent={EnableCriterialPercent};EnableEventTrigger={EnableEventTrigger};IsFaultIfNoTrigger={IsFaultIfNoTrigger};"
  679. // // ;
  680. // //}
  681. // //public void SetValue(string config)
  682. // //{
  683. // // if (string.IsNullOrEmpty(config))
  684. // // return;
  685. // // string[] items = config.Split(';');
  686. // // foreach (var item in items)
  687. // // {
  688. // // if (string.IsNullOrEmpty(item))
  689. // // continue;
  690. // // string[] pairs = item.Split('=');
  691. // // if (pairs.Length != 2)
  692. // // continue;
  693. // // Parallel.ForEach(this.GetType().GetProperties(),
  694. // // property =>
  695. // // {
  696. // // PropertyInfo pi = (PropertyInfo) property;
  697. // // if (pi.Name == pairs[0])
  698. // // {
  699. // // try
  700. // // {
  701. // // var convertedValue = Convert.ChangeType(pairs[1], pi.PropertyType);
  702. // // var originValue = Convert.ChangeType(pi.GetValue(this, null), pi.PropertyType);
  703. // // if (originValue != convertedValue)
  704. // // {
  705. // // pi.SetValue(this, convertedValue, null);
  706. // // }
  707. // // }
  708. // // catch (Exception)
  709. // // {
  710. // // }
  711. // // }
  712. // // });
  713. // // }
  714. // //}
  715. //}
  716. #endregion
  717. }