123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Xml;
- using Aitex.UI.RecipeEditor.Core;
- using Aitex.UI.RecipeEditor.View;
- using ExcelLibrary.SpreadSheet;
- using Microsoft.Win32;
- using Xceed.Wpf.DataGrid;
- namespace Aitex.UI.RecipeEditor
- {
- public class RecipeEditorControlViewModel : INotifyPropertyChanged
- {
- public List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>> UndoList { get; set; }
- public List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>> RedoList { get; set; }
- public bool IsUndoEnabled { get { return UndoList != null && UndoList.Count > 0; } }
- public bool IsRedoEnabled { get { return RedoList != null && RedoList.Count > 0; } }
- public ObservableCollection<RecipeRow> RecipeRows { get; set; }
- private ObservableCollection<RecipeRow> _previousRecipeRows { get; set; }
- private string _valueBeforeEditing { get; set; }
- private string _currentRecipeVariationName = string.Empty;
- private SmartCellData _currentEditingCellData { get; set; }
- public List<Tuple<int/*row no*/, int/*col no*/, string/*var name*/, string/*reason*/>> Errors { get; set; }
- public List<Tuple<string, string>> CreateRecipeList { get; set; }
- public List<Tuple<string, string>> OpenRecipeList { get; set; }
- public DataGridControl DataGridControl { get; set; }
- public int CurrentRunningStepNo { get; set; }
- public Visibility SingleAppElementVisibility { get; set; }
- public Visibility RecipeInfoTextVisibility { get; set; }
- public ICommand ShowDetailedErrInfoCommand { get; set; }
- public ICommand EditRecipeInfoCommand { get; set; }
- //public ICommand CellContentChangedCommand { get; set; }
- public ICommand RightClickCommand { get; set; }
- public ICommand OpenLocalRecipeCommand { get; set; }
- public ICommand ExpandGroupCommand { get; set; }
- public ICommand CollapseGroupCommand { get; set; }
- public ICommand SaveRecipeCommand { get; set; }
- public ICommand RecipeHelpDocCommand { get; set; }
- public ICommand RecipeExport2ExcelCommand { get; set; }
- public ICommand ToggleHideSameCommand { get; set; }
- public ICommand UndoCommand { get; set; }
- public ICommand RedoCommand { get; set; }
- public ICommand SmartCellEditorLoadedCommand { get; set; }
- public ICommand SmartCellEditorUnloadedCommand { get; set; }
- public RecipeHead RecipeHead { get; set; }
- public bool IsBusy { get; set; }
- public bool IsHideSameContent { get; set; }
- public string RecipeInfo { get; set; }
- public HashSet<string> MaskedTechNames { get; set; }
- public HashSet<string> MaskedCatalogNames { get; set; }
- public event EventHandler OnSaveRecipeFile;
- public event EventHandler OnLocalRecipeOpened;
- public event EventHandler OnLoadRecipeContent;
- public bool IsRecipeModified { get; set; }
- public string UserName { set; get; }
- //private List<Tuple<string, string, string>> SourceDilteInjectRestrictions { get; set; }
- private Dictionary<string, string> _preDefinedRecipeVars { get; set; }
- private List<Tuple<string/*varName*/, string/*check condition*/, string/*message*/>> _validationRules { get; set; }
- private List<string> _checkVariables { get; set; }
- private Dictionary<string, int> RowVarNameDic { get; set; }
- private Dictionary<int, List<SmartCellData>> _copiedColumnDatas = new Dictionary<int, List<SmartCellData>>();
- private Dictionary<string/*CatalogName*/, Dictionary<string/*GroupName*/, List<RecipeVariableDefine/*StepList*/>>> _recipeReadingFormat;
- private Dictionary<string/*ModuleName*/, List<string>/*each item's control name*/> _recipeSavingFormat;
- private string _currentRecipeFormatContent;
- public bool IsBarcodeEnabled
- {
- get; set;
- }
- public Visibility IsBarcodeVisibility
- {
- get
- {
- return IsBarcodeEnabled ? Visibility.Visible : Visibility.Hidden;
- }
- }
- private string _defaultEndPointValue { get; set; }
- /// <summary>
- /// class construction
- /// </summary>
- public RecipeEditorControlViewModel()
- {
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>();
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>();
- //if(SingleAppElementVisibility
- CreateRecipeList = new List<Tuple<string, string>>();
- OpenRecipeList = new List<Tuple<string, string>>();
- foreach (var item in GetDefinedRecipeVariations())
- {
- CreateRecipeList.Add(new Tuple<string, string>("配置:" + item, item));
- OpenRecipeList.Add(new Tuple<string, string>("转换为配置:" + item, item));
- }
- RecipeInfoTextVisibility = Visibility.Collapsed;
- SingleAppElementVisibility = Visibility.Collapsed;
- RightClickCommand = new DelegatedCommand((o) => true, (o) => RightClickAction());
- ExpandGroupCommand = new DelegatedCommand((o) => true, (o) => ExpandGroups());
- CollapseGroupCommand = new DelegatedCommand((o) => true, (o) => CollapseGroups());
- SaveRecipeCommand = new DelegatedCommand((o) => true, (o) => SaveRecipeFile());
- OpenLocalRecipeCommand = new DelegatedCommand((o) => true, (o) => OpenLocalRecipe());
- ShowDetailedErrInfoCommand = new DelegatedCommand((o) => true, (o) => ShowDetailedErrInformation());
- EditRecipeInfoCommand = new DelegatedCommand((o) => true, (o) => EditRecipeInformation());
- RecipeHelpDocCommand = new DelegatedCommand((o) => true, (o) => ShowHelpDocView());
- RecipeExport2ExcelCommand = new DelegatedCommand((o) => true, (o) => Export2Excel());
- ToggleHideSameCommand = new DelegatedCommand((o) => true, (o) => ToggleHideSameContent());
- UndoCommand = new DelegatedCommand((o) => true, (o) => UndoOperation(o));
- RedoCommand = new DelegatedCommand((o) => true, (o) => RedoOperation(o));
- SmartCellEditorLoadedCommand = new DelegatedCommand((o) => true, (o) => SmartCellEditorLoaded(o));
- SmartCellEditorUnloadedCommand = new DelegatedCommand((o) => true, (o) => SmartCellEditorUnloaded(o));
- }
- /// <summary>
- /// When smart cell editor loaded
- /// </summary>
- /// <param name="obj"></param>
- private void SmartCellEditorLoaded(object obj)
- {
- _currentEditingCellData = obj as SmartCellData;
- if (_currentEditingCellData == null) return;
- _valueBeforeEditing = _currentEditingCellData.Value;
- _previousRecipeRows = CloneRecipeRowData(RecipeRows);
- }
- /// <summary>
- /// make a clone of current recipe row data
- /// </summary>
- /// <returns></returns>
- private ObservableCollection<RecipeRow> CloneRecipeRowData(ObservableCollection<RecipeRow> oldData)
- {
- ObservableCollection<RecipeRow> newRecipeRows = new ObservableCollection<RecipeRow>();
- foreach (var item in oldData)
- {
- var newRecipeRow = new RecipeRow() { CatalogName = item.CatalogName, FriendlyName = item.FriendlyName, TechnicalName = item.TechnicalName, RecipeItems = new ObservableCollection<SmartCellData>() };
- newRecipeRows.Add(newRecipeRow);
- foreach (var item2 in item.RecipeItems)
- {
- var newRecipeItem = new SmartCellData() { Background = item2.Background, ErrInfo = item2.ErrInfo, FontWeight = item2.FontWeight, Foreground = item2.Foreground, IsHidden = item2.IsHidden, IsMasked = item2.IsMasked, IsRunning = item2.IsRunning, RecipeVariableDefine = item2.RecipeVariableDefine, Value = item2.Value };
- newRecipeRow.RecipeItems.Add(newRecipeItem);
- }
- }
- return newRecipeRows;
- }
- /// <summary>
- /// When smart cell editor unloaded
- /// </summary>
- /// <param name="obj"></param>
- private void SmartCellEditorUnloaded(object obj)
- {
- if (_currentEditingCellData != null && _currentEditingCellData.Value != _valueBeforeEditing)
- {
- IsRecipeModified = true;
- var ret = OverrideSelectedCellsData();
- if (ret < 2)
- AddUndoHistory(string.Format("第{0}步({1})",
- _currentEditingCellData.ColIndex + 1,
- _currentEditingCellData.RecipeVariableDefine.CatalogName + _currentEditingCellData.RecipeVariableDefine.FriendlyName), _previousRecipeRows);
- else
- AddUndoHistory(string.Format("第{0}步({1})等{2}个单元格数据",
- _currentEditingCellData.ColIndex + 1,
- _currentEditingCellData.RecipeVariableDefine.CatalogName + _currentEditingCellData.RecipeVariableDefine.FriendlyName, ret), _previousRecipeRows);
- }
- RefreshCellsDisplay(false);
- }
- /// <summary>
- /// Adding undo history
- /// </summary>
- /// <param name="description"></param>
- /// <param name="recipeRows"></param>
- private void AddUndoHistory(string description, ObservableCollection<RecipeRow> recipeRows)
- {
- System.Diagnostics.Debug.WriteLine(description);
- if (recipeRows == null)
- return;
- string shortDesc = "";
- if (description.Length > 50)
- {
- shortDesc = description.Substring(0, 50);
- shortDesc += "...";
- }
- else
- {
- shortDesc = description;
- }
- UndoList.Insert(0, new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(shortDesc, description, recipeRows, Guid.NewGuid()));
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(UndoList.ToList());
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>();
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- }
- /// <summary>
- /// Redo something here
- /// </summary>
- private void RedoOperation(object obj)
- {
- try
- {
- if (RedoList == null || RedoList.Count == 0)
- return;
- Guid redoId = Guid.Empty;
- if (obj == null)
- redoId = RedoList[0].Item4;
- else
- redoId = (Guid)obj;
- var itemIndex = RedoList.FindIndex((o) => o.Item4 == redoId);
- if (itemIndex < 0)
- return;
- UndoList.Reverse();
- for (int i = 0; i <= itemIndex; i++)
- {
- if (i == 0)
- UndoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(RedoList[i].Item1, RedoList[i].Item2, CloneRecipeRowData(RecipeRows), RedoList[i].Item4));
- else
- UndoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(RedoList[i].Item1, RedoList[i].Item2, RedoList[i - 1].Item3, RedoList[i].Item4));
- }
- UndoList.Reverse();
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(UndoList.ToList());
- RecipeRows = RedoList[itemIndex].Item3;
- RedoList.RemoveRange(0, itemIndex + 1);
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(RedoList.ToList());
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("恢复动作失败!\r\n\r\n" + ex.Message, "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- }
- /// <summary>
- /// Undo something here
- /// </summary>
- private void UndoOperation(object obj)
- {
- try
- {
- if (UndoList == null || UndoList.Count == 0)
- return;
- Guid undoId = Guid.Empty;
- if (obj == null)
- undoId = UndoList[0].Item4;
- else
- undoId = (Guid)obj;
- var itemIndex = UndoList.FindIndex((o) => o.Item4 == undoId);
- if (itemIndex < 0)
- return;
- RedoList.Reverse();
- for (int i = 0; i <= itemIndex; i++)
- {
- if (i == 0)
- RedoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(UndoList[i].Item1, UndoList[i].Item2, CloneRecipeRowData(RecipeRows), UndoList[i].Item4));
- else
- RedoList.Add(new Tuple<string, string, ObservableCollection<RecipeRow>, Guid>(UndoList[i].Item1, UndoList[i].Item2, UndoList[i - 1].Item3, UndoList[i].Item4));
- }
- RedoList.Reverse();
- RedoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(RedoList.ToList());
- RecipeRows = UndoList[itemIndex].Item3;
- UndoList.RemoveRange(0, itemIndex + 1);
- UndoList = new List<Tuple<string, string, ObservableCollection<RecipeRow>, Guid>>(UndoList.ToList());
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("撤销动作失败!\r\n\r\n" + ex.Message, "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- }
- /// <summary>
- /// hide or show same content before and after one step
- /// </summary>
- private void ToggleHideSameContent()
- {
- IsHideSameContent = !IsHideSameContent;
- RefreshCellsDisplay(false);
- }
- /// <summary>
- /// get recipe variations
- /// </summary>
- /// <returns></returns>
- public List<string> GetDefinedRecipeVariations()
- {
- var list1 = new List<string>();
- var dir = new System.IO.FileInfo(Process.GetCurrentProcess().MainModule.FileName).Directory;
- string cfgPath = dir + "\\Config\\";
- var di = new System.IO.DirectoryInfo(cfgPath);
- if (di.Exists)
- {
- foreach (var item in di.GetFiles("*.xml"))
- {
- list1.Add(item.Name.Substring(0, item.Name.Length - item.Extension.Length));
- }
- }
- return list1;
- }
- /// <summary>
- /// Export to excel
- /// </summary>
- private void Export2Excel()
- {
- try
- {
- if (RecipeRows == null) return;
- var dlg = new SaveFileDialog();
- dlg.DefaultExt = ".xls";
- dlg.Filter = "Excel文件 (.xls)|*.xls|所有文件 (*.*)|*.*";
- if (dlg.ShowDialog() == true)
- {
- if (File.Exists(dlg.FileName))
- File.Delete(dlg.FileName);
- Workbook workbook = new Workbook();
- Worksheet worksheet = new Worksheet("First Sheet");
- XmlDocument doc = new XmlDocument();
- doc.LoadXml(_currentRecipeFormatContent);
- var catalogNodes = doc.SelectNodes("TableRecipeFormat/Catalog");
- int groupRowIndex = 0;
- int stepRowIndex = 0;
- int catalogRowIndex = 0;
- foreach (XmlElement cNode in catalogNodes)
- {
- XmlNodeList sNodes = cNode.SelectNodes("Group/Step");
- string catalogHeader = cNode.Attributes["DisplayName"].Value;
- worksheet.Cells[catalogRowIndex, 0] = new ExcelLibrary.SpreadSheet.Cell(catalogHeader);
- catalogRowIndex += sNodes.Count;
- XmlNodeList gNodes = cNode.SelectNodes("Group");
- foreach (XmlElement gNode in gNodes)
- {
- XmlNodeList stepNodes = gNode.SelectNodes("Step");
- string groupHeader = gNode.Attributes["DisplayName"].Value;
- worksheet.Cells[groupRowIndex, 1] = new ExcelLibrary.SpreadSheet.Cell(groupHeader);
- groupRowIndex += stepNodes.Count;
- foreach (XmlElement nd in stepNodes)
- {
- string stepHeader = nd.Attributes["DisplayName"].Value;
- worksheet.Cells[stepRowIndex, 2] = new ExcelLibrary.SpreadSheet.Cell(stepHeader);
- stepRowIndex++;
- }
- }
- }
- string recipeContent = GetRecipeContentString();
- XmlDocument rcp = new XmlDocument();
- rcp.LoadXml(recipeContent);
- XmlNodeList stepNodeList = rcp.SelectNodes("/TableRecipeData/Step");
- for (int stepNo = 0; stepNo < stepNodeList.Count; stepNo++)
- {
- var dataDic = new Dictionary<string, string>();
- foreach (XmlAttribute att in (stepNodeList[stepNo] as XmlElement).Attributes)
- {
- dataDic.Add(att.Name, att.Value);
- }
- //fill sub node's attributes
- foreach (XmlElement subStep in stepNodeList[stepNo].ChildNodes)
- {
- foreach (XmlAttribute att in subStep.Attributes)
- {
- dataDic.Add(att.Name, att.Value);
- }
- foreach (XmlElement subsubStep in subStep.ChildNodes)
- {
- foreach (XmlAttribute att2 in subsubStep.Attributes)
- {
- dataDic.Add(att2.Name, att2.Value);
- }
- }
- }
- long length = dataDic.LongCount();
- int step = 0;
- foreach (string key in dataDic.Keys)
- {
- worksheet.Cells.ColumnWidth[(ushort)step] = 4000;
- var cellContent = dataDic[key];
- double v;
- if (double.TryParse(cellContent, out v))
- {
- worksheet.Cells[step, stepNo + 3] = new ExcelLibrary.SpreadSheet.Cell(v);
- }
- else
- {
- worksheet.Cells[step, stepNo + 3] = new ExcelLibrary.SpreadSheet.Cell(cellContent);
- }
- step++;
- }
- }
- workbook.Worksheets.Add(worksheet);
- workbook.Save(dlg.FileName);
- MessageBox.Show(string.Format("成功导出到Excel文件!\r\n\r\n{0}", dlg.FileName), "导出", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("导出Excel文件发生异常!\r\n\r\n" + ex.Message, "导出", MessageBoxButton.OK, MessageBoxImage.Error);
- }
- }
- /// <summary>
- /// Show recipe information
- /// </summary>
- private void ShowHelpDocView()
- {
- var view = RecipeHelpView.Instance;
- view.Owner = Application.Current.MainWindow;
- view.DataContext = this;
- if (view.Visibility == Visibility.Visible)
- view.Hide();
- else
- view.Show();
- }
- /// <summary>
- /// Edit recipe information
- /// </summary>
- private void EditRecipeInformation()
- {
- RecipeInfoEditor editor = new RecipeInfoEditor() { RecipeHead = this.RecipeHead, Owner = Application.Current.MainWindow };
- editor.ShowDialog();
- InvokePropertyChanged("RecipeHead");
- }
- public void EnableBarcode(bool enable)
- {
- IsBarcodeEnabled = enable;
- InvokePropertyChanged("IsBarcodeVisibility");
- }
- public void SetCurrentUser(string user)
- {
- UserName = user;
- InvokePropertyChanged("UserName");
- }
- public void SetEndPointDefaultValue(string defaultValue)
- {
- _defaultEndPointValue = defaultValue;
- }
- /// <summary>
- /// Show recipe information
- /// </summary>
- private void ShowDetailedErrInformation()
- {
- var view = ErrorInformationDetailsView.Instance;
- view.Owner = Application.Current.MainWindow;
- view.DataContext = this;
- if (view.Visibility == Visibility.Visible)
- view.Hide();
- else
- view.ShowDialog();
- }
- /// <summary>
- /// Update selected cells data
- /// </summary>
- /// <returns>overrided cells number</returns>
- private int OverrideSelectedCellsData()
- {
- int overridedCellsNum = 0;
- if (_currentEditingCellData != null)
- {
- var finalCellData = _currentEditingCellData;
- bool containsEditingCell = false;
- foreach (var item in DataGridControl.SelectedCellRanges)
- {
- int startColIndex = Math.Min(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int endColIndex = Math.Max(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int startRowIndex = Math.Min(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- int endRowIndex = Math.Max(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- if (startColIndex > 0 && startColIndex <= RecipeRows[0].RecipeItems.Count &&
- endColIndex > 0 && endColIndex <= RecipeRows[0].RecipeItems.Count &&
- startRowIndex >= 0 && startRowIndex < RecipeRows.Count &&
- endRowIndex >= 0 && endRowIndex < RecipeRows.Count)
- {
- for (int m = startRowIndex; m <= endRowIndex; m++)
- {
- for (int n = startColIndex; n <= endColIndex; n++)
- {
- int rowIndex = m;
- int colIndex = n - 1;
- if (RecipeRows[rowIndex].RecipeItems[colIndex] == _currentEditingCellData)
- {
- containsEditingCell = true;
- break;
- }
- }
- }
- }
- }
- if (containsEditingCell)
- {
- foreach (var item in DataGridControl.SelectedCellRanges)
- {
- int startColIndex = Math.Min(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int endColIndex = Math.Max(item.ColumnRange.StartIndex, item.ColumnRange.EndIndex);
- int startRowIndex = Math.Min(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- int endRowIndex = Math.Max(item.ItemRange.StartIndex, item.ItemRange.EndIndex);
- if (startColIndex > 0 && startColIndex <= RecipeRows[0].RecipeItems.Count &&
- endColIndex > 0 && endColIndex <= RecipeRows[0].RecipeItems.Count &&
- startRowIndex >= 0 && startRowIndex < RecipeRows.Count &&
- endRowIndex >= 0 && endRowIndex < RecipeRows.Count)
- {
- for (int m = startRowIndex; m <= endRowIndex; m++)
- {
- for (int n = startColIndex; n <= endColIndex; n++)
- {
- int rowIndex = m;
- int colIndex = n - 1;
- if (RecipeRows[rowIndex].RecipeItems[colIndex].RecipeVariableDefine.CellType == finalCellData.RecipeVariableDefine.CellType)
- {
- overridedCellsNum++;
- RecipeRows[rowIndex].RecipeItems[colIndex].Value = finalCellData.Value;
- RecipeRows[rowIndex].RecipeItems[colIndex].InvokePropertyChanged();
- }
- }
- }
- }
- }
- }
- }
- return overridedCellsNum;
- }
- /// <summary>
- /// Open local recipe operation
- /// </summary>
- /// <param name="recipeDefineFilePath"></param>
- public void OpenLocalRecipe(string recipeVariationName = "")
- {
- var dlg = new OpenFileDialog();
- dlg.DefaultExt = ".rcp";
- dlg.Filter = "Recipe File (.rcp)|*.rcp|All (*.*)|*.*";
- if (dlg.ShowDialog() == true)
- {
- try
- {
- XmlDocument rcpDoc = new XmlDocument();
- rcpDoc.Load(dlg.FileName);
- string recipeVariation = recipeVariationName;
- if (string.IsNullOrEmpty(recipeVariation))
- {
- var root = rcpDoc.SelectSingleNode("/TableRecipeData") as XmlElement;
- recipeVariation = root.Attributes["RecipeVersion"].Value;
- }
- var startupPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
- string dir = System.IO.Path.GetDirectoryName(startupPath);
- List<Aitex.Controls.RecipeCompare.Item> map = CustomXmlSerializer.Deserialize<List<Aitex.Controls.RecipeCompare.Item>>(new System.IO.FileInfo(System.IO.Path.Combine(dir, "map.xml")));
- Func<Aitex.Controls.RecipeCompare.Item, bool> predicate = item => item.Name.Equals(recipeVariation);
- System.IO.FileInfo fi = new System.IO.FileInfo(string.Format("{0}\\config\\{1}.xml", dir, map.Any(predicate) ? map.Single(predicate).No : recipeVariation));
- if (fi.Exists)
- {
- XmlDocument doc = new XmlDocument();
- doc.Load(fi.FullName);
- string formatXml = doc.SelectSingleNode("/Aitex/TableRecipeFormat").OuterXml;
- string recipeXml = rcpDoc.SelectSingleNode("/TableRecipeData").OuterXml;
- LoadRecipe(formatXml, recipeXml);
- if (OnLocalRecipeOpened != null)
- OnLocalRecipeOpened.Invoke(new Tuple<string, string>(recipeVariation, dlg.FileName), null);
- }
- else
- {
- MessageBox.Show(string.Format("工艺程序版本{0}的描述文件不存在,无法正确识别该版本的工艺程序文件。", recipeVariation), "工艺程序打开失败",
- MessageBoxButton.OK, MessageBoxImage.Error);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- 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",
- MessageBoxButton.OK, MessageBoxImage.Error);
- }
- }
- }
- /// <summary>
- /// Save recipe file
- /// </summary>
- private void SaveRecipeFile()
- {
- try
- {
- if (Errors != null && Errors.Count > 0)
- {
- var ret = MessageBox.Show(string.Format("Recipe have {0} error,continue save?", Errors.Count), "Save", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
- if (ret != MessageBoxResult.Yes)
- return;
- }
- if (OnSaveRecipeFile != null)
- {
- IsRecipeModified = false;
- OnSaveRecipeFile.Invoke(GetRecipeContentString(), null);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- MessageBox.Show("save recipe failed!\r\n\r\n" + ex.Message, "Save", MessageBoxButton.OK, MessageBoxImage.Warning);
- }
- }
- /// <summary>
- /// get string typed recipe content
- /// </summary>
- /// <returns></returns>
- public string GetRecipeContentString()
- {
- if (string.IsNullOrEmpty(UserName))
- {
- var dlg1 = new Aitex.UI.RecipeEditor.UserNameInput() { Owner = Application.Current.MainWindow };
- var ret = dlg1.ShowDialog();
- if (ret.HasValue && ret.Value)
- {
- UserName = dlg1.UserName;
- }
- }
- RecipeHead.LastRevisionTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss");
- RecipeHead.LastModifiedBy = UserName;
- InvokePropertyChanged("RecipeHead");
- if (RecipeRows == null || RecipeRows.Count == 0 || RecipeRows[0].RecipeItems == null || RecipeRows[0].RecipeItems.Count == 0)
- return string.Empty;
- //Dictionary<string/*CatalogName*/, Dictionary<string/*GroupName*/, List<RecipeVariableDefine/*StepList*/>>> _recipeReadingFormat;
- XmlDocument doc = new XmlDocument();
- var rootNode = doc.CreateElement("TableRecipeData");
- rootNode.SetAttribute("RecipeVersion", RecipeHead.RecipeVariation);
- rootNode.SetAttribute("CreatedBy", RecipeHead.CreatedBy);
- rootNode.SetAttribute("CreationTime", RecipeHead.CreationTime);
- rootNode.SetAttribute("LastRevisedBy", RecipeHead.LastModifiedBy);
- rootNode.SetAttribute("LastRevisionTime", RecipeHead.LastRevisionTime);
- if (!string.IsNullOrEmpty(RecipeHead.PressureMode))
- {
- rootNode.SetAttribute("PressureMode", RecipeHead.PressureMode);
- }
- if (!string.IsNullOrEmpty(RecipeHead.BasePressure))
- {
- rootNode.SetAttribute("BasePressure", RecipeHead.BasePressure);
- }
- if (!string.IsNullOrEmpty(RecipeHead.Chamber1Temp))
- {
- rootNode.SetAttribute("Chamber1Temperature", RecipeHead.Chamber1Temp);
- }
- if (!string.IsNullOrEmpty(RecipeHead.Chamber2Temp))
- {
- rootNode.SetAttribute("Chamber2Temperature", RecipeHead.Chamber2Temp);
- }
- if (!string.IsNullOrEmpty(RecipeHead.PinDownPressure))
- {
- rootNode.SetAttribute("PinDownPressure", RecipeHead.PinDownPressure);
- }
- if (!string.IsNullOrEmpty(RecipeHead.VentingPinState))
- {
- rootNode.SetAttribute("VentingPinState", RecipeHead.VentingPinState);
- }
- if (!string.IsNullOrEmpty(RecipeHead.PumpingPinState))
- {
- rootNode.SetAttribute("PumpingPinState", RecipeHead.PumpingPinState);
- }
- if (!string.IsNullOrEmpty(RecipeHead.PumpDownLimit))
- {
- rootNode.SetAttribute("PumpDownLimit", RecipeHead.PumpDownLimit);
- }
- if (!string.IsNullOrEmpty(RecipeHead.PurgeActive))
- {
- rootNode.SetAttribute("PurgeActive", RecipeHead.PurgeActive);
- }
- if (!string.IsNullOrEmpty(RecipeHead.NotToPurgeOrVent))
- {
- rootNode.SetAttribute("NotToPurgeOrVent", RecipeHead.NotToPurgeOrVent);
- }
- rootNode.SetAttribute("Barcode", RecipeHead.Barcode);
- rootNode.SetAttribute("Description", RecipeHead.Description);
- doc.AppendChild(rootNode);
- for (int stepIndex/* 0-> */ = 0; stepIndex < RecipeRows[0].RecipeItems.Count; stepIndex++)
- {
- var stepNode = doc.CreateElement("Step");
- rootNode.AppendChild(stepNode);
- foreach (var module in _recipeSavingFormat)
- {
- var moduleName = module.Key;
- XmlElement subNode = stepNode;
- if (!string.IsNullOrEmpty(moduleName))
- {
- string[] pathArr = moduleName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
- for (int i = 0; i < pathArr.Length; i++)
- {
- var snd = subNode.SelectSingleNode(pathArr[i]) as XmlElement;
- if (snd == null)
- {
- var nd = doc.CreateElement(pathArr[i]);
- subNode.AppendChild(nd);
- subNode = nd;
- }
- else
- {
- subNode = snd;
- }
- }
- }
- foreach (var controlName in module.Value)
- {
- if (controlName == "StepNo")
- {
- subNode.SetAttribute(controlName, string.Format("第{0}步", stepIndex + 1));
- }
- else
- {
- var recipeRow = RecipeRows.First((o) => o.TechnicalName == controlName);
- if (recipeRow == null) continue;
- /*to compatiable with old recipe editor, always fill 'black space' to loop step*/
- if (controlName == "Loop" && string.IsNullOrEmpty(recipeRow.RecipeItems[stepIndex].Value))
- subNode.SetAttribute(controlName, " ");
- else
- {
- subNode.SetAttribute(controlName, recipeRow.RecipeItems[stepIndex].Value);
- //bool isJump = recipeRow.RecipeItems[stepIndex].IsJump;
- //if (isJump)
- //{
- // string deviceType = recipeRow.RecipeItems[stepIndex].RecipeVariableDefine.DeviceType;
- // if (deviceType == "MFC" || deviceType == "PC")
- // subNode.SetAttribute(controlName + ".IsJump", isJump.ToString());
- //}
- }
- }
- }
- }
- }
- return doc.OuterXml;
- }
- /// <summary>
- /// expand groups
- /// </summary>
- private void ExpandGroups()
- {
- try
- {
- foreach (CollectionViewGroup item in DataGridControl.Items.Groups)
- {
- DataGridControl.ExpandGroup(item);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// collapse groups
- /// </summary>
- private void CollapseGroups()
- {
- try
- {
- foreach (CollectionViewGroup item in DataGridControl.Items.Groups)
- {
- DataGridControl.CollapseGroup(item);
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// right click context menu
- /// </summary>
- private void RightClickAction()
- {
- DataGridControl.ContextMenu = null;
- //get selected column information
- List<int> selectedColumns = new List<int>();
- foreach (var item in DataGridControl.SelectedCellRanges)
- {
- bool dir = item.ColumnRange.StartIndex <= item.ColumnRange.EndIndex;
- if (dir)
- {
- for (int i = item.ColumnRange.StartIndex; i <= item.ColumnRange.EndIndex; i++)
- {
- if (i > 0)
- if (!selectedColumns.Contains(i)) selectedColumns.Add(i);
- }
- }
- else
- {
- for (int i = item.ColumnRange.StartIndex; i >= item.ColumnRange.EndIndex; i--)
- {
- if (i > 0)
- if (!selectedColumns.Contains(i)) selectedColumns.Add(i);
- }
- }
- }
- selectedColumns.Sort();
- //debug only
- /*
- string s = "";
- foreach (var item in selectedColumns)
- {
- s += "," + item;
- }
- MessageBox.Show(s);
- * */
- //generate context menu
- ContextMenu cms = new ContextMenu();
- if (selectedColumns.Count > 0)
- {
- string colStrings = "";
- foreach (var item in selectedColumns)
- {
- if (string.IsNullOrEmpty(colStrings))
- colStrings = item.ToString();
- else
- colStrings += "," + item.ToString();
- }
- MenuItem mi;
- cms.Items.Add(new MenuItem() { Header = string.Format(" 当前选中第{0}步", colStrings), FontFamily = new FontFamily("Arial,SimSun"), IsEnabled = false, Background = Brushes.Gray, Foreground = Brushes.White });
- //copy
- mi = new MenuItem() { Header = " 复制", FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns.ToList() };
- mi.Click += (s, e) =>
- {
- try
- {
- var list = (s as MenuItem).Tag as List<int>;
- _copiedColumnDatas.Clear();
- foreach (var colId in list)
- {
- _copiedColumnDatas.Add(colId/*index from 1*/, new List<SmartCellData>());
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- var oldCellData = RecipeRows[i].RecipeItems[colId - 1];
- var newCellData = new SmartCellData() { Value = oldCellData.Value, RecipeVariableDefine = oldCellData.RecipeVariableDefine };
- _copiedColumnDatas[colId].Add(newCellData);
- }
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- if (selectedColumns.Count < RecipeRows[0].RecipeItems.Count)
- {
- mi = new MenuItem() { Header = " 剪切", FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns.ToList() };
- mi.Click += (s, e) =>
- {
- try
- {
- AddUndoHistory("剪切", CloneRecipeRowData(RecipeRows));
- var list = (s as MenuItem).Tag as List<int>;
- _copiedColumnDatas.Clear();
- foreach (var colId in list)
- {
- _copiedColumnDatas.Add(colId/*index from 1*/, new List<SmartCellData>());
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- var oldCellData = RecipeRows[i].RecipeItems[colId - 1];
- var newCellData = new SmartCellData() { Value = oldCellData.Value, RecipeVariableDefine = oldCellData.RecipeVariableDefine };
- _copiedColumnDatas[colId].Add(newCellData);
- }
- }
- foreach (var item in RecipeRows)
- {
- var collection = new ObservableCollection<SmartCellData>();
- for (int index = 0; index < item.RecipeItems.Count; index++)
- {
- if (list.Contains(index + 1))
- continue;
- collection.Add(item.RecipeItems[index]);
- }
- item.RecipeItems = collection;
- }
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- mi = new MenuItem() { Header = " 删除", FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns.ToList() };
- mi.Click += (s, e) =>
- {
- try
- {
- AddUndoHistory("删除", CloneRecipeRowData(RecipeRows));
- var list = (s as MenuItem).Tag as List<int>;
- foreach (var item in RecipeRows)
- {
- var collection = new ObservableCollection<SmartCellData>();
- for (int index = 0; index < item.RecipeItems.Count; index++)
- {
- if (list.Contains(index + 1))
- continue;
- collection.Add(item.RecipeItems[index]);
- }
- item.RecipeItems = collection;
- }
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- }
- if (selectedColumns.Count == 1 && _copiedColumnDatas.Count > 0)
- {
- mi = new MenuItem() { Header = string.Format(" 插入第{0}步后", selectedColumns[0]/*, _copiedColumnDatas.Count*/), FontFamily = new FontFamily("Arial,SimSun"), Tag = selectedColumns[0] };
- mi.Click += (s, e) =>
- {
- try
- {
- AddUndoHistory("插入", CloneRecipeRowData(RecipeRows));
- int insertColId = (int)(s as MenuItem).Tag;
- for (int rowIndex = 0; rowIndex < RecipeRows.Count; rowIndex++)
- {
- var collection = new ObservableCollection<SmartCellData>();
- for (int index = 0; index < insertColId; index++)
- {
- collection.Add(RecipeRows[rowIndex].RecipeItems[index]);
- }
- foreach (var col in _copiedColumnDatas)
- {
- collection.Add(new SmartCellData() { Value = col.Value[rowIndex].Value, RecipeVariableDefine = col.Value[rowIndex].RecipeVariableDefine });
- }
- for (int index = insertColId; index < RecipeRows[rowIndex].RecipeItems.Count; index++)
- {
- collection.Add(RecipeRows[rowIndex].RecipeItems[index]);
- }
- RecipeRows[rowIndex].RecipeItems = collection;
- }
- RefreshDataGrid();
- RefreshCellsDisplay(false);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- };
- cms.Items.Add(mi);
- }
- }
- //show context menu
- DataGridControl.ContextMenu = cms;
- cms.Visibility = Visibility.Visible;
- }
- /// <summary>
- /// Parse recipe content with recipe format
- /// </summary>
- /// <param name="recipeFormat"></param>
- /// <param name="recipeContent"></param>
- /// <param name="selectedStepNo"></param>
- public void LoadRecipe(string recipeFormat, string recipeContent, int selectedStepNo = -1)
- {
- CurrentRunningStepNo = selectedStepNo;
- IsHideSameContent = false;
- IsRecipeModified = false;
- RecipeHead = new RecipeEditor.RecipeHead();
- DataGridControl.ContextMenu = null;
- RecipeInfo = "";
- IsBusy = true;
- InvokePropertyChanged("IsBusy");
- UndoList.Clear();
- RedoList.Clear();
- InvokePropertyChanged("UndoList");
- InvokePropertyChanged("RedoList");
- InvokePropertyChanged("IsUndoEnabled");
- InvokePropertyChanged("IsRedoEnabled");
- try
- {
- RecipeRows = new ObservableCollection<RecipeRow>();
- _recipeReadingFormat = new Dictionary<string, Dictionary<string, List<RecipeVariableDefine>>>();
- _recipeSavingFormat = new Dictionary<string, List<string>>();
- //parse recipe format
- XmlDocument formatXml = new XmlDocument();
- formatXml.LoadXml(recipeFormat);
- _currentRecipeFormatContent = formatXml.OuterXml;
- //reading recipe variation
- string recipeVariationName = formatXml.SelectSingleNode("TableRecipeFormat").Attributes["RecipeVersion"].Value;
- if (String.Compare(recipeVariationName, _currentRecipeVariationName) != 0)
- {
- //if variation name is different from previous loaded recipe -> clear all previous copied recipe columns
- _copiedColumnDatas.Clear();
- }
- _currentRecipeVariationName = recipeVariationName;
- //reading recipe validation releated parameters
- _preDefinedRecipeVars = new Dictionary<string, string>();
- foreach (XmlElement nd in formatXml.SelectNodes("/TableRecipeFormat/Validation/Predefine/Item"))
- {
- _preDefinedRecipeVars.Add(nd.Attributes["VarName"].Value, nd.Attributes["Value"].Value);
- }
- //reading check variables
- _checkVariables = new List<string>();
- foreach (XmlElement nd in formatXml.SelectNodes("/TableRecipeFormat/Validation/CheckVariable/Var"))
- {
- string varName = nd.Attributes["Name"].Value;
- _checkVariables.Add(varName);
- }
- //reading validation rules
- _validationRules = new List<Tuple<string, string, string>>();
- foreach (XmlElement nd in formatXml.SelectNodes("/TableRecipeFormat/Validation/Restriction/Rule"))
- {
- string varName = nd.Attributes["VarName"].Value;
- string checkCondition = nd.Attributes["CheckCondition"].Value.Replace("<", "<").Replace(">", ">");
- string message = nd.Attributes["Message"].Value.Replace("'", "\"");
- _validationRules.Add(new Tuple<string, string, string>(varName, checkCondition, message));
- }
- //parsing recipe format xml file
- foreach (XmlElement catalogNode in formatXml.SelectNodes("/TableRecipeFormat/Catalog"))
- {
- string catalogName = catalogNode.Attributes["DisplayName"].Value;
- _recipeReadingFormat.Add(catalogName, new Dictionary<string, List<RecipeVariableDefine>>());
- foreach (XmlElement groupNode in catalogNode.SelectNodes("Group"))
- {
- string groupName = groupNode.Attributes["DisplayName"].Value;
- _recipeReadingFormat[catalogName].Add(groupName, new List<RecipeVariableDefine>());
- foreach (XmlElement stepNode in groupNode.SelectNodes("Step"))
- {
- string stepModuleName = stepNode.Attributes["ModuleName"].Value;
- string stepDeviceType = stepNode.Attributes["DeviceType"].Value;
- string stepDisplayName = stepNode.Attributes["DisplayName"].Value;
- string stepControlName = stepNode.Attributes["ControlName"].Value;
- string stepInputType = stepNode.Attributes["InputType"].Value;
- string stepDescription = stepNode.HasAttribute("Desc") ? stepNode.Attributes["Desc"].Value : "";
- double stepMin = double.Parse(stepNode.HasAttribute("Min") ? stepNode.Attributes["Min"].Value : "0");
- double stepMax = double.Parse(stepNode.HasAttribute("Max") ? stepNode.Attributes["Max"].Value : "0");
- var selectionList = new List<Tuple<string, string>>();
- foreach (XmlElement selectionNode in stepNode.SelectNodes("Item"))
- {
- selectionList.Add(new Tuple<string, string>(selectionNode.Attributes["ControlName"].Value, selectionNode.Attributes["DisplayName"].Value));
- }
- if (!_recipeSavingFormat.ContainsKey(stepModuleName)) _recipeSavingFormat.Add(stepModuleName, new List<string>());
- _recipeSavingFormat[stepModuleName].Add(stepControlName);
- if (stepControlName == "StepNo")
- continue;
- _recipeReadingFormat[catalogName][groupName].Add(new RecipeVariableDefine()
- {
- CellType = (CellType)Enum.Parse(typeof(CellType), stepInputType),
- Description = stepDescription,
- DeviceType = stepDeviceType,
- DropdownItemList = selectionList,
- MaxValue = stepMax,
- //MinValue = stepDeviceType.Equals("MFC",StringComparison.InvariantCultureIgnoreCase)? stepMax*2.0/100: stepMin,
- MinValue = stepMin,
- GroupName = groupName,
- CatalogName = catalogName,
- TechnicalName = stepControlName,
- FriendlyName = stepDisplayName
- });
- }
- }
- }
- //parse recipe content
- XmlDocument contentXml = new XmlDocument();
- contentXml.LoadXml(recipeContent);
- contentXml.DocumentElement.SetAttribute("RecipeVersion", _currentRecipeVariationName);
- //read recipe head
- //em. RecipeVersion="Ace" CreatedBy="tech" CreationTime="2013-02-02T12:36:02" LastRevisedBy="Peter" LastRevisionTime="2013-10-22T13:30:29" Description="5e46af80-49f9-4b4f-b04b-bc911fb292f8"
- RecipeHead.CreatedBy = contentXml.DocumentElement.HasAttribute("CreatedBy") ? contentXml.DocumentElement.Attributes["CreatedBy"].Value : "(无)";
- RecipeHead.CreationTime = contentXml.DocumentElement.HasAttribute("CreationTime") ? contentXml.DocumentElement.Attributes["CreationTime"].Value : "(无)";
- RecipeHead.LastModifiedBy = contentXml.DocumentElement.HasAttribute("LastRevisedBy") ? contentXml.DocumentElement.Attributes["LastRevisedBy"].Value : "(无)";
- RecipeHead.LastRevisionTime = contentXml.DocumentElement.HasAttribute("LastRevisionTime") ? contentXml.DocumentElement.Attributes["LastRevisionTime"].Value : "(无)";
- if (contentXml.DocumentElement.HasAttribute("PressureMode"))
- {
- RecipeHead.PressureMode = contentXml.DocumentElement.Attributes["PressureMode"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("BasePressure"))
- {
- RecipeHead.BasePressure = contentXml.DocumentElement.Attributes["BasePressure"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("PumpDownLimit"))
- {
- RecipeHead.PumpDownLimit = contentXml.DocumentElement.Attributes["PumpDownLimit"].Value;
- }
-
- if (contentXml.DocumentElement.HasAttribute("Chamber1Temperature"))
- {
- RecipeHead.Chamber1Temp = contentXml.DocumentElement.Attributes["Chamber1Temperature"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("Chamber2Temperature"))
- {
- RecipeHead.Chamber2Temp = contentXml.DocumentElement.Attributes["Chamber2Temperature"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("PinDownPressure"))
- {
- RecipeHead.PinDownPressure = contentXml.DocumentElement.Attributes["PinDownPressure"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("VentingPinState"))
- {
- RecipeHead.VentingPinState = contentXml.DocumentElement.Attributes["VentingPinState"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("PumpingPinState"))
- {
- RecipeHead.PumpingPinState = contentXml.DocumentElement.Attributes["PumpingPinState"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("PurgeActive"))
- {
- RecipeHead.PurgeActive = contentXml.DocumentElement.Attributes["PurgeActive"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("NotToPurgeOrVent"))
- {
- RecipeHead.NotToPurgeOrVent = contentXml.DocumentElement.Attributes["NotToPurgeOrVent"].Value;
- }
- if (contentXml.DocumentElement.HasAttribute("Barcode"))
- {
- RecipeHead.Barcode = contentXml.DocumentElement.Attributes["Barcode"].Value;
- }
- RecipeHead.RecipeVariation = contentXml.DocumentElement.HasAttribute("RecipeVersion") ? contentXml.DocumentElement.Attributes["RecipeVersion"].Value : "(NULL)";
- RecipeHead.Description = contentXml.DocumentElement.HasAttribute("Description") ? contentXml.DocumentElement.Attributes["Description"].Value : "(NULL)";
- var allRecipeItems = new List<Dictionary<string, string>>();
- foreach (XmlElement stepNode in contentXml.SelectNodes("/TableRecipeData/Step"))
- {
- var stepDic = new Dictionary<string, string>();
- allRecipeItems.Add(stepDic);
- foreach (XmlAttribute att in stepNode.Attributes)
- {
- stepDic.Add(att.Name, att.Value);
- }
- foreach (XmlElement innerStep in stepNode.ChildNodes)
- {
- foreach (XmlAttribute att in innerStep.Attributes)
- {
- stepDic.Add(att.Name, att.Value);
- }
- foreach (XmlElement innerInnerStep in innerStep.ChildNodes)
- {
- foreach (XmlAttribute att in innerInnerStep.Attributes)
- {
- stepDic.Add(att.Name, att.Value);
- }
- }
- }
- }
- //generate view model
- RowVarNameDic = new Dictionary<string, int>();
- int rowIndex = 0;
- foreach (var catalog in _recipeReadingFormat.Keys)
- {
- foreach (var group in _recipeReadingFormat[catalog].Keys)
- {
- foreach (var var1 in _recipeReadingFormat[catalog][group])
- {
- var singleRow = new RecipeRow() { CatalogName = catalog, FriendlyName = /*group + */var1.FriendlyName, TechnicalName = var1.TechnicalName };
- for (int stepNo = 0; stepNo < allRecipeItems.Count; stepNo++)
- {
- var stepCell = new SmartCellData() { RecipeVariableDefine = var1 };
- if (allRecipeItems[stepNo].ContainsKey(var1.TechnicalName))
- {
- stepCell.Value = allRecipeItems[stepNo][var1.TechnicalName];
- //stepCell.ShowsJumpControl = false;
- //if (var1.CellType == CellType.NumInput)
- //{
- // if (var1.DeviceType == "MFC" || var1.DeviceType == "PC")
- // {
- // string jumpString = var1.TechnicalName + ".IsJump";
- // stepCell.IsJump = allRecipeItems[stepNo].ContainsKey(jumpString) ? bool.Parse(allRecipeItems[stepNo][jumpString]) : false;
- // stepCell.ShowsJumpControl = true;
- // }
- //}
- }
- else
- stepCell.Value = "0";
- singleRow.RecipeItems.Add(stepCell);
- }
- RecipeRows.Add(singleRow);
- RowVarNameDic.Add(var1.TechnicalName, rowIndex++);
- }
- }
- }
- //refresh datagrid
- RefreshDataGrid();
- //refresh recipe information
- RefreshCellsDisplay();
- if (OnLoadRecipeContent != null)
- OnLoadRecipeContent.Invoke(recipeContent, null);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- //LOG.Write("", ex);
- }
- IsBusy = false;
- InvokePropertyChanged("IsBusy");
- }
- /// <summary>
- /// 检查变量ramp rate
- /// </summary>
- /// <param name="stepNo"></param>
- /// <param name="rampEnable"></param>
- /// <param name="varName"></param>
- /// <param name="rampTime"></param>
- /// <param name="maxRampUpRate"></param>
- /// <param name="maxRampDownRate"></param>
- /// <returns>False:check ok, True: check failed</returns>
- public bool CheckRampRate(int stepNo, string rampEnable, string varName, string rampTime, double maxRampUpRate, double maxRampDownRate)
- {
- try
- {
- if (stepNo <= 0) return false;
- int rowIndex = RowVarNameDic[varName];
- double currentValue = double.Parse(RecipeRows[rowIndex].RecipeItems[stepNo].Value);
- //if (varName == "AZone.Setpoint" || varName == "BZone.Setpoint" || varName == "CZone.Setpoint" || varName == "DZone.Setpoint")
- //{
- // int heatControlModeIndex = RowVarNameDic["Heater.Mode"];
- // string curStepHeatCtrlMode = RecipeRows[heatControlModeIndex].RecipeItems[stepNo].Value;
- // string lastStepHeatCtrlMode = RecipeRows[heatControlModeIndex].RecipeItems[stepNo - 1].Value;
- // if (curStepHeatCtrlMode != lastStepHeatCtrlMode)
- // {
- // if (!(lastStepHeatCtrlMode.Equals("CurrentControl") && curStepHeatCtrlMode.Equals("PyroTempControl")))
- // return false;
- // int endbyIndex = RowVarNameDic["EndBy"];
- // int endValueIndex = RowVarNameDic["EndValue"];
- // string endby = RecipeRows[endbyIndex].RecipeItems[stepNo - 1].Value;
- // EndByCondition endbyEnum;
- // if (!Enum.TryParse(endby, out endbyEnum)) return false;
- // if (endbyEnum != EndByCondition.PmTempGt && endbyEnum != EndByCondition.PmTempLt) return false;
- // string end = RecipeRows[endValueIndex].RecipeItems[stepNo - 1].Value;
- // double endValue;
- // if (!double.TryParse(end, out endValue)) return false;
- // return CheckRampRate(rampEnable, rampTime, maxRampUpRate, maxRampDownRate, endValue, currentValue);
- // }
- //}
- double prevValue = double.Parse(RecipeRows[rowIndex].RecipeItems[stepNo - 1].Value);
- return CheckRampRate(rampEnable, rampTime, maxRampUpRate, maxRampDownRate, prevValue, currentValue);
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- return true;
- }
- }
- bool CheckRampRate(string rampEnable, string rampTime, double maxRampUpRate, double maxRampDownRate, double prevValue, double currentValue)
- {
- bool isRampEnable = bool.Parse(rampEnable);
- //string[] timeStr = rampTime.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- //string tt = string.Join(":", timeStr);
- TimeSpan timeSpan;
- TimeSpan.TryParse(rampTime, out timeSpan);
- double totalTimeSec = timeSpan.TotalSeconds;
- double diff = currentValue - prevValue;
- if (!isRampEnable || totalTimeSec <= 0)
- {
- if (diff != 0) return true;
- return false;
- }
- else
- {
- double rampRate = diff / totalTimeSec;
- return (rampRate > 0 && rampRate >= maxRampUpRate) || (rampRate < 0 && rampRate <= -maxRampDownRate);
- }
- }
- /// <summary>
- /// Refresh datagrid cell data display
- /// </summary>
- /// <param name="moving2RunningStepPosition">True: moving to current running step position</param>
- public void RefreshCellsDisplay(bool moving2RunningStepPosition = true)
- {
- try
- {
- if (RecipeRows == null || RecipeRows.Count < 2)
- return;
- Errors = new List<Tuple<int, int, string, string>>();
- Dictionary<int, string> dicEndby = new Dictionary<int, string>();
- Dictionary<int, string> dicPressureMode = new Dictionary<int, string>();
- Dictionary<int, string> dicRfMode = new Dictionary<int, string>();
- Dictionary<int, string> dicRfMatchProcessMode = new Dictionary<int, string>();
- Dictionary<int, string> dicSetMatchPositionC1 = new Dictionary<int, string>();
- Dictionary<int, string> dicSetMatchPositionC2 = new Dictionary<int, string>();
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- for (int j = 0; j < RecipeRows[i].RecipeItems.Count; j++)
- {
- var cell = RecipeRows[i].RecipeItems[j];
- cell.RowIndex = i;
- cell.ColIndex = j;
- cell.ErrInfo = string.Empty;
- bool logicEnable = true;
- if (cell.RecipeVariableDefine.TechnicalName == "EndBy")
- dicEndby[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "ThrottleValve.SetMode")
- {
- dicPressureMode[j] = cell.Value;
- }
- if (cell.RecipeVariableDefine.TechnicalName == "PressureControl.SetTVMode")
- {
- dicPressureMode[j] = cell.Value;
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetMode")
- dicRfMode[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchProcessMode")
- dicRfMatchProcessMode[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC1")
- dicSetMatchPositionC1[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC2")
- dicSetMatchPositionC2[j] = cell.Value;
- if (cell.RecipeVariableDefine.TechnicalName == "Time")
- {
- logicEnable = dicEndby.ContainsKey(j) && (dicEndby[j] == "EndByStepTime" ||
- dicEndby[j] == "EndByHeatUp" ||
- dicEndby[j] == "EndByEndPoint");
- }
- if (cell.RecipeVariableDefine.TechnicalName == "ThrottleValve.SetPosition")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPositionCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "ThrottleValve.SetPressure")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPressureCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "PressureControl.SetTVPosition")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPositionCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "PressureControl.SetTVPressure")
- {
- logicEnable = dicPressureMode.ContainsKey(j) && dicPressureMode[j] == "TVPressureCtrl";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetPulsingFrequency")
- {
- logicEnable = dicRfMode.ContainsKey(j) && dicRfMode[j] == "PulsingMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetPulsingDuty")
- {
- logicEnable = dicRfMode.ContainsKey(j) && dicRfMode[j] == "PulsingMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf.SetPowerOnTime")
- {
- logicEnable = dicEndby.ContainsKey(j) && dicEndby[j] == "EndByRfTime";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf1.SetPowerOnTime")
- {
- logicEnable = dicEndby.ContainsKey(j) && dicEndby[j] == "EndByRfTime";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Rf2.SetPowerOnTime")
- {
- logicEnable = dicEndby.ContainsKey(j) && dicEndby[j] == "EndByRfTime";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "EPD.SetConfig")
- {
- logicEnable = dicEndby.ContainsKey(j) && dicEndby[j] == "EndByEndPoint";
- if (string.IsNullOrEmpty(cell.Value) || cell.Value.StartsWith("n/a"))
- cell.Value = _defaultEndPointValue;
- }
-
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchProcessMode")
- {
- logicEnable = dicRfMatchProcessMode.ContainsKey(j);// && dicRfMatchProcessMode[j] == "TritonPresetMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC1")
- {
- logicEnable = dicSetMatchPositionC1.ContainsKey(j);// && dicRfMatchProcessMode[j] == "TritonPresetMode";
- }
- if (cell.RecipeVariableDefine.TechnicalName == "Match.SetMatchPositionC2")
- {
- logicEnable = dicSetMatchPositionC2.ContainsKey(j);// && dicRfMatchProcessMode[j] == "TritonPresetMode";
- }
- cell.IsMasked = !logicEnable;
- //update diff variable numbers
- if (cell.RecipeVariableDefine.TechnicalName == "Ramp")
- {
- //更新当前步骤中Ramp的变量数据
- if (j == 0)
- {
- cell.Tag = 0;
- }
- else
- {
- int rampNum = 0;
- for (int s1 = 0; s1 < RecipeRows.Count; s1++)
- {
- if (RecipeRows[s1].CatalogName == "StepInfo")// RecipeRows[s1].RecipeItems[j].RecipeVariableDefine.CellType == CellType.ReadOnly)
- continue;
- string preValue = RecipeRows[s1].RecipeItems[j - 1].Value;
- string curValue = RecipeRows[s1].RecipeItems[j].Value;
- if (RecipeRows[s1].RecipeItems[j].RecipeVariableDefine.CellType == CellType.NumInput)
- {
- double pd, cd;
- if (double.TryParse(preValue, out pd) && double.TryParse(curValue, out cd))
- if (pd != cd) rampNum++;
- }
- else if (String.Compare(preValue, curValue, false) != 0)
- {
- rampNum++;
- }
- }
- cell.Tag = rampNum;
- }
- cell.InvokePropertyChanged();
- }
- #region mask (hide or show cell content)
- if ((MaskedTechNames != null && MaskedTechNames.Contains(cell.RecipeVariableDefine.TechnicalName)) ||
- (MaskedCatalogNames != null && MaskedCatalogNames.Contains(cell.RecipeVariableDefine.CatalogName)) || !logicEnable)
- cell.IsMasked = true;
- else
- cell.IsMasked = false;
- #endregion mask (hide or show cell content)
- #region check cell data range
- switch (cell.RecipeVariableDefine.CellType)
- {
- case CellType.CheckBox:
- {
- if (string.Compare(cell.Value, "true", true) == 0 || string.Compare(cell.Value, "false", true) == 0)
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- else
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- }
- break;
- case CellType.EditableSelection:
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- break;
- case CellType.NumInput:
- {
- double min = cell.RecipeVariableDefine.MinValue;
- double max = cell.RecipeVariableDefine.MaxValue;
- double v;
- if (!double.TryParse(cell.Value, out v))
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- else if (v > max || v < 0 || (v < min && v > max * 0.1 / 100))
- {
- string reason = string.Format("Value'{0}',Out of Range {1}~{2}", cell.Value, min, max);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- else
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- }
- break;
- case CellType.ReadOnlySelection:
- {
- if (cell.RecipeVariableDefine.DropdownItemList != null && cell.RecipeVariableDefine.DropdownItemList.Find((o) => o.Item1 == cell.Value) != null)
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- else
- {
- string reason = string.Format("Value'{0}' is not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- }
- break;
- case CellType.ReadOnly:
- case CellType.TextInput:
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- break;
- case CellType.TimeInput:
- {
- string[] arr = cell.Value.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- int h, mi, s;
- if (arr.Length == 3 && int.TryParse(arr[0], out h) && int.TryParse(arr[1], out mi) && int.TryParse(arr[2], out s) && h >= 0 && mi >= 0 && mi <= 59 && s >= 0 && s <= 59)
- {
- cell.ErrInfo = "";
- cell.Background = Brushes.Transparent;
- }
- else
- {
- string reason = string.Format("value'{0}' is not valid", cell.Value);
- Errors.Add(new Tuple<int, int, string, string>(i, j, cell.RecipeVariableDefine.FriendlyName, reason));
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- }
- }
- break;
- }
- #endregion check cell data range
- #region mark data trend / hide same content
- if (j == 0) //step one
- {
- cell.Foreground = Brushes.Black;
- cell.FontWeight = FontWeights.Normal;
- cell.IsHidden = false;
- cell.InvokePropertyChanged();
- cell.IsMasked = !logicEnable;
- continue;
- }
- var preCell = RecipeRows[i].RecipeItems[j - 1];
- if (cell.RecipeVariableDefine.CellType == CellType.NumInput)
- {
- double preValue = 0;
- double.TryParse(preCell.Value.ToString(), out preValue);
- double curValue = 0;
- double.TryParse(cell.Value.ToString(), out curValue);
- if (curValue > preValue)
- {
- cell.Foreground = Brushes.Red;
- cell.FontWeight = FontWeights.Bold;
- }
- else if (curValue < preValue)
- {
- cell.Foreground = Brushes.Blue;
- cell.FontWeight = FontWeights.Bold;
- }
- else
- {
- cell.Foreground = Brushes.Black;
- cell.FontWeight = FontWeights.Normal;
- }
- }
- else
- {
- //not number type
- cell.Foreground = Brushes.Black;
- cell.FontWeight = FontWeights.Normal;
- }
- if (IsHideSameContent && cell.Value == preCell.Value)
- cell.IsHidden = true;
- else
- cell.IsHidden = false;
- //!logicEnable;
- cell.IsMasked = !logicEnable;
- //if (!logicEnable)
- //{
- // cell.Background = Brushes.DarkGray;
- // cell.IsMasked = true;
- //}
- #endregion mark data trend / hide same content
- cell.InvokePropertyChanged();
- }
- }
- #region check loop
- int loopRowId = -1;
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- if (RecipeRows[i].TechnicalName == "Loop")
- {
- loopRowId = i;
- break;
- }
- }
- for (int j = 0; j < RecipeRows[loopRowId].RecipeItems.Count; j++)
- {
- var cell = RecipeRows[loopRowId].RecipeItems[j];
- bool isLoopStart = Regex.IsMatch(cell.Value, @"^Loop\x20\d+$");
- bool isLoopEnd = Regex.IsMatch(cell.Value, @"^Loop End$");
- bool isNullOrEmpty = string.IsNullOrWhiteSpace(cell.Value);
- if (!isLoopEnd && !isLoopStart && !isNullOrEmpty)
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, j, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- if (isLoopEnd)
- {
- string reason = "Loop Start 缺失";
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, j, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- else if (isLoopStart)
- {
- for (int k = j + 1; k < RecipeRows[loopRowId].RecipeItems.Count; k++)
- {
- cell = RecipeRows[loopRowId].RecipeItems[k];
- bool isCurStepLoopStart = Regex.IsMatch(cell.Value, @"^Loop\x20\d+$");
- bool isCurStepLoopEnd = Regex.IsMatch(cell.Value, @"^Loop End$");
- isNullOrEmpty = string.IsNullOrWhiteSpace(cell.Value);
- if (!isCurStepLoopEnd && !isCurStepLoopStart && !isNullOrEmpty)
- {
- string reason = string.Format("Value '{0}' not valid", cell.Value);
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, k, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- else if (isCurStepLoopStart)
- {
- string reason = "前面循环没有结束,不能设置新的Loop Start标志";
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, k, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- else if (isCurStepLoopEnd)
- {
- //mark loop steps with blue background
- for (int m1 = j; m1 <= k; m1++)
- {
- var curCell = RecipeRows[loopRowId].RecipeItems[m1];
- if (curCell.Background == Brushes.Transparent)
- curCell.Background = Brushes.LightGreen;
- curCell.InvokePropertyChanged();
- }
- j = k;
- break;
- }
- if (k == RecipeRows[loopRowId].RecipeItems.Count - 1)
- {
- j = k;
- string reason = "Loop End 缺失";
- cell.ErrInfo = reason;
- cell.Background = Brushes.Pink;
- Errors.Add(new Tuple<int, int, string, string>(loopRowId, k, cell.RecipeVariableDefine.FriendlyName, reason));
- }
- }
- }
- }
- #endregion check loop
- #region recipe parameter validation
- //using (var lua = new LuaInterface.Lua())
- //{
- // //is special recipe?
- // //bool IsSpecialRecipe = true;
- // //{
- // // int heaterModeRowIndex = RowVarNameDic["Heater.Mode"];
- // // int aZoneSetpointIndex = RowVarNameDic["AZone.Setpoint"];
- // // int bZoneSetpointIndex = RowVarNameDic["BZone.Setpoint"];
- // // int cZoneSetpointIndex = RowVarNameDic["CZone.Setpoint"];
- // // int dZoneSetpointIndex = RowVarNameDic.ContainsKey("DZone.Setpoint") ? RowVarNameDic["DZone.Setpoint"] : aZoneSetpointIndex;
- // // for (int stepIndex = 0; stepIndex < RecipeRows[0].RecipeItems.Count; stepIndex++)
- // // {
- // // if (RecipeRows[heaterModeRowIndex].RecipeItems[stepIndex].Value != "CurrentControl" ||
- // // RecipeRows[aZoneSetpointIndex].RecipeItems[stepIndex].Value != "0" ||
- // // RecipeRows[bZoneSetpointIndex].RecipeItems[stepIndex].Value != "0" ||
- // // RecipeRows[cZoneSetpointIndex].RecipeItems[stepIndex].Value != "0" ||
- // // RecipeRows[dZoneSetpointIndex].RecipeItems[stepIndex].Value != "0")
- // // {
- // // IsSpecialRecipe = false;
- // // break;
- // // }
- // // }
- // //}
- // ////set get ramp rate function
- // //lua.RegisterFunction("CheckRampRate", this, GetType().GetMethod("CheckRampRate"));
- // //lua.DoString(string.Format("IsProductionRecipe={0};",(!IsSpecialRecipe).ToString().ToLower()));
- // for (int stepIndex = 0; stepIndex < RecipeRows[0].RecipeItems.Count; stepIndex++)
- // {
- // //set stepNo
- // lua.DoString(string.Format("StepNo={0};", stepIndex));
- // //reading var from current recipe step
- // foreach (var checkVar in _checkVariables)
- // {
- // if (!RowVarNameDic.ContainsKey(checkVar))
- // {
- // System.Diagnostics.Debug.WriteLine("检查不到变量定义," + checkVar);
- // continue;
- // }
- // try
- // {
- // int varId = RowVarNameDic[checkVar];
- // if (RecipeRows[varId].RecipeItems[stepIndex].RecipeVariableDefine.CellType == CellType.NumInput)
- // lua.DoString(string.Format("{0}={1};", RecipeRows[varId].RecipeItems[stepIndex].RecipeVariableDefine.TechnicalName.Replace(".", "_"), RecipeRows[varId].RecipeItems[stepIndex].Value));
- // else
- // lua.DoString(string.Format("{0}=\"{1}\";", RecipeRows[varId].RecipeItems[stepIndex].RecipeVariableDefine.TechnicalName.Replace(".", "_"), RecipeRows[varId].RecipeItems[stepIndex].Value));
- // }
- // catch (Exception ex)
- // {
- // System.Diagnostics.Debug.WriteLine("校验异常," + ex);
- // }
- // }
- // //reading from recipe format file
- // foreach (string key in _preDefinedRecipeVars.Keys)
- // {
- // string varValueString = _preDefinedRecipeVars[key];
- // double varValue;
- // if (double.TryParse(varValueString, out varValue))
- // lua.DoString(string.Format("{0}={1};", key, varValue));
- // else
- // lua.DoString(string.Format("{0}=\"{1}\";", key, varValueString));
- // }
- // //do valation
- // foreach (var rule in _validationRules)
- // {
- // lua.DoString(string.Format("if {0} then hasErr=1 else hasErr=0 end", rule.Item2));
- // bool hasError = ((int)lua.GetNumber("hasErr")) == 1;
- // if (hasError)
- // {
- // lua.DoString(string.Format("message=string.format({0});", rule.Item3));
- // string reason = lua.GetString("message");
- // var rowId = RowVarNameDic[rule.Item1];
- // var cell = RecipeRows[rowId].RecipeItems[stepIndex];
- // cell.ErrInfo = reason;
- // cell.Background = Brushes.Pink;
- // Errors.Add(new Tuple<int, int, string, string>(rowId, stepIndex, cell.RecipeVariableDefine.FriendlyName, reason));
- // cell.InvokePropertyChanged();
- // }
- // }
- // }
- //}
- #endregion recipe parameter validation
- #region update material cell data
- int materialRowId = -1;
- for (int colId = 0; colId < RecipeRows[0].RecipeItems.Count; colId++)
- {
- string materialName = "";
- for (int rowId = 0; rowId < RecipeRows.Count; rowId++)
- {
- string curMo = "";
- if (materialRowId == -1 && RecipeRows[rowId].RecipeItems[colId].RecipeVariableDefine.TechnicalName == "Material")
- {
- materialRowId = rowId;
- }
- var cell = RecipeRows[rowId].RecipeItems[colId];
- if (cell.RecipeVariableDefine.CellType == CellType.ReadOnlySelection && String.Compare(cell.Value, "flow", true) == 0)
- {
- string moName = cell.RecipeVariableDefine.TechnicalName.Split('.')[0].ToLower();
- string displayName = cell.RecipeVariableDefine.FriendlyName.Replace("_", ".").Split('.')[0].ToLower();
- if (moName.Contains("cp2mg_1") || displayName.Contains("cp2mg_1")) curMo = "Mg1";
- else if (moName.Contains("cp2mg_2") || displayName.Contains("cp2mg_2")) curMo = "Mg2";
- else if (moName.Contains("cp2mg_3") || displayName.Contains("cp2mg_3")) curMo = "Mg3";
- else if (moName.Contains("cp2mg_4") || displayName.Contains("cp2mg_4")) curMo = "Mg4";
- else if (moName.Contains("cp2mg") || displayName.Contains("cp2mg")) curMo = "Mg";
- else if (moName.Contains("tmin") || displayName.Contains("tmin")) curMo = "In";
- else if (moName.Contains("tmin_1") || displayName.Contains("tmin_1")) curMo = "In1";
- else if (moName.Contains("tmin_2") || displayName.Contains("tmin_2")) curMo = "In2";
- else if (moName.Contains("tmin_3") || displayName.Contains("tmin_3")) curMo = "In3";
- else if (moName.Contains("tmin_4") || displayName.Contains("tmin_4")) curMo = "In4";
- else if (moName.Contains("tmga") || displayName.Contains("tmga")) curMo = "TMG";
- else if (moName.Contains("tmga_1") || displayName.Contains("tmga_1")) curMo = "TMG1";
- else if (moName.Contains("tmga_2") || displayName.Contains("tmga_2")) curMo = "TMG2";
- else if (moName.Contains("tmga_3") || displayName.Contains("tmga_3")) curMo = "TMG3";
- else if (moName.Contains("tmga_4") || displayName.Contains("tmga_4")) curMo = "TMG4";
- else if (moName.Contains("tega") || displayName.Contains("tega")) curMo = "TEG";
- else if (moName.Contains("tega_1") || displayName.Contains("tega_1")) curMo = "TEG1";
- else if (moName.Contains("tega_2") || displayName.Contains("tega_2")) curMo = "TEG2";
- else if (moName.Contains("tega_3") || displayName.Contains("tega_3")) curMo = "TEG3";
- else if (moName.Contains("tega_4") || displayName.Contains("tega_4")) curMo = "TEG4";
- else if (moName.Contains("tmal") || displayName.Contains("tmal")) curMo = "TAl";
- else if (moName.Contains("tmal_1") || displayName.Contains("tmal_1")) curMo = "TAl1";
- else if (moName.Contains("tmal_2") || displayName.Contains("tmal_2")) curMo = "TAl2";
- else if (moName.Contains("tmal_3") || displayName.Contains("tmal_3")) curMo = "TAl3";
- else if (moName.Contains("tmal_4") || displayName.Contains("tmal_4")) curMo = "TAl4";
- else if (moName.Contains("nh3source") || displayName.Contains("nh3source")) curMo = "NH3";
- else if (moName.Contains("si")) curMo = "Si";
- if (!string.IsNullOrEmpty(curMo))
- {
- if (string.IsNullOrEmpty(materialName))
- materialName = curMo;
- else
- materialName += "|" + curMo;
- }
- }
- }
- if (materialRowId >= 0)
- {
- RecipeRows[materialRowId].RecipeItems[colId].Value = materialName;
- RecipeRows[materialRowId].RecipeItems[colId].InvokePropertyChanged();
- }
- }
- #endregion update material cell data
- #region update column header
- if (DataGridControl.Columns.Count - 1 == RecipeRows[0].RecipeItems.Count)
- {
- var redColHeader = (DataTemplate)DataGridControl.FindResource("columnRedTitleTemplate");
- var blackColHeader = (DataTemplate)DataGridControl.FindResource("columnBlackTitleTemplate");
- for (int j = 0; j < RecipeRows[0].RecipeItems.Count; j++)
- {
- DataGridControl.Columns[j + 1].Title = string.Format("{0}|{2}\r\n{1}", j + 1, RecipeRows[0].RecipeItems[j].Value, RecipeRows[2].RecipeItems[j].Value);
- if (Errors.Find((o) => o.Item2 == j) != null)
- DataGridControl.Columns[j + 1].TitleTemplate = redColHeader;
- else
- DataGridControl.Columns[j + 1].TitleTemplate = blackColHeader;
- }
- }
- #endregion update column header
- #region if running state, highlight current running step, move horizontal bar to current running step
- if (CurrentRunningStepNo > 0 && DataGridControl.Columns.Count > 2)
- {
- for (int rowId = 0; rowId < RecipeRows.Count; rowId++)
- {
- for (int colId = 0; colId < RecipeRows[0].RecipeItems.Count; colId++)
- {
- var cell = RecipeRows[rowId].RecipeItems[colId];
- if (colId + 1 == CurrentRunningStepNo)
- {
- cell.IsRunning = true;
- }
- else
- {
- cell.IsRunning = false;
- }
- cell.InvokePropertyChanged("IsRunning");
- }
- }
- if (moving2RunningStepPosition)
- {
- Task.Factory.StartNew(() =>
- {
- System.Threading.Thread.Sleep(200);
- DataGridControl.Dispatcher.Invoke(new Action(() =>
- {
- double singleWidth = DataGridControl.Columns[1].Width;
- double horizontalOffset = (CurrentRunningStepNo - 2) * singleWidth;
- if (DataGridControl.ScrollViewer != null)
- {
- if (horizontalOffset > DataGridControl.ScrollViewer.ScrollableWidth)
- horizontalOffset = DataGridControl.ScrollViewer.ScrollableWidth;
- if (horizontalOffset < 0)
- horizontalOffset = 0;
- DataGridControl.ScrollViewer.ScrollToHorizontalOffset(horizontalOffset);
- }
- }));
- });
- }
- }
- #endregion if running state, highlight current running step, move horizontal bar to current running step
- //calc recipe time
- CalcRecipeTime();
- //invoke property
- InvokePropertyChanged("Errors");
- }
- catch (Exception ex)
- {
- MessageBox.Show("工艺程序校验出错!\r\n\r\n" + ex.Message, "出错", MessageBoxButton.OK, MessageBoxImage.Error);
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// reload datagrid content
- /// </summary>
- private void RefreshDataGrid()
- {
- try
- {
- //generate columns in Grid
- DataGridControl.CurrentColumn = null;
- if (DataGridControl.Columns.Count > 0)
- DataGridControl.Columns.Clear();
- var template = (DataTemplate)DataGridControl.FindResource("CustomTemplate");
- var rowTemplate = (DataTemplate)DataGridControl.FindResource("RowHeadTemplate");
- DataGridControl.Columns.Add(new Xceed.Wpf.DataGrid.Column()
- {
- Width = 140,
- Title = " ",
- FieldName = ".",
- CellContentTemplate = rowTemplate
- });
- var cellEditor = DataGridControl.DefaultCellEditors[typeof(SmartCellData)];// DefaultCellEditorSelector.SelectCellEditor(typeof(SmartCellData));
- for (int index = 0; index < RecipeRows[0].RecipeItems.Count; index++)
- {
- //var col = new Xceed.Wpf.DataGrid.Column();
- DataGridControl.Columns.Add(new Xceed.Wpf.DataGrid.Column()
- {
- Title = string.Format("【{0}】\r\n{1}", index + 1, RecipeRows[0].RecipeItems[index].Value),
- FieldName = string.Format("RecipeItems[{0}]", index),
- CellContentTemplate = template,
- AllowSort = false,
- Width = 120,
- MaxWidth = 120,
- CellEditor = cellEditor
- });
- }
- InvokePropertyChanged("RecipeRows");
- InvokePropertyChanged("RecipeHead");
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(ex.Message);
- }
- }
- /// <summary>
- /// calc recipe total time
- /// </summary>
- private void CalcRecipeTime()
- {
- int timeStepRowId = -1;
- int loopStepRowId = -1;
- for (int i = 0; i < RecipeRows.Count; i++)
- {
- if (RecipeRows[i].TechnicalName == "Time")
- timeStepRowId = i;
- if (RecipeRows[i].TechnicalName == "Loop")
- loopStepRowId = i;
- if (loopStepRowId != -1 && timeStepRowId != -1)
- break;
- }
- TimeSpan tspan = new TimeSpan();
- for (int stepNo = 0; stepNo < RecipeRows[timeStepRowId].RecipeItems.Count; stepNo++)
- {
- string loopStr = RecipeRows[loopStepRowId].RecipeItems[stepNo].Value;
- bool isLoopStart = Regex.IsMatch(loopStr, @"^Loop\x20\d+$");
- if (isLoopStart)
- {
- int loopNum = int.Parse(loopStr.ToLower().Replace("loop", "").Replace(" ", ""));
- TimeSpan ts = new TimeSpan();
- for (int innerStepNo = stepNo; innerStepNo < RecipeRows[timeStepRowId].RecipeItems.Count; innerStepNo++)
- {
- loopStr = RecipeRows[loopStepRowId].RecipeItems[innerStepNo].Value;
- stepNo = innerStepNo;
- string timeDuration = RecipeRows[timeStepRowId].RecipeItems[innerStepNo].Value;
- string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- if (timeArr.Length == 3)
- {
- int h, mi, s;
- if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
- {
- var tt = new TimeSpan(h, mi, s);
- ts += tt;
- }
- }
- bool isLoopEnd = Regex.IsMatch(loopStr, @"^Loop End$");
- if (isLoopEnd)
- {
- tspan += new TimeSpan(ts.Ticks * loopNum);
- break;
- }
- }
- }
- else
- {
- string timeDuration = RecipeRows[timeStepRowId].RecipeItems[stepNo].Value;
- string[] timeArr = timeDuration.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
- if (timeArr.Length == 3)
- {
- int h, mi, s;
- if (int.TryParse(timeArr[0], out h) && int.TryParse(timeArr[1], out mi) && int.TryParse(timeArr[2], out s))
- {
- var ts = new TimeSpan(h, mi, s);
- tspan += ts;
- }
- }
- }
- }
- RecipeInfo = string.Format("共{0}步,总时间{1}:{2}:{3}", RecipeRows[0].RecipeItems.Count, (int)tspan.TotalHours, tspan.Minutes.ToString("00"), tspan.Seconds.ToString("00"));
- InvokePropertyChanged("RecipeInfo");
- }
- #region INotifyPropertyChanged
- public event PropertyChangedEventHandler PropertyChanged;
- public void InvokePropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- #endregion INotifyPropertyChanged
- }
- public class RecipeRow
- {
- private ObservableCollection<SmartCellData> _recipeItems = new ObservableCollection<SmartCellData>();
- public RecipeRow(params SmartCellData[] vars)
- {
- foreach (var var in vars)
- _recipeItems.Add(var);
- }
- public string CatalogName { get; set; }
- public string FriendlyName { get; set; }
- public string TechnicalName { get; set; }
- public ObservableCollection<SmartCellData> RecipeItems
- {
- get { return _recipeItems; }
- set { _recipeItems = value; }
- }
- }
- /// <summary>
- /// Recipe head
- /// </summary>
- public class RecipeHead
- {
- public string RecipeVariation { get; set; }
- public string CreationTime { get; set; }
- public string LastRevisionTime { get; set; }
- public string CreatedBy { get; set; }
- public string LastModifiedBy { get; set; }
- public string PressureMode { get; set; }
- public string Description { get; set; }
- public string BasePressure
- {
- get; set;
- }
- public string PumpDownLimit
- {
- get; set;
- }
- public string PurgeActive
- {
- get; set;
- }
- public string NotToPurgeOrVent
- {
- get; set;
- }
- public string Barcode
- {
- get; set;
- }
- public string Chamber1Temp
- {
- get; set;
- }
- public string Chamber2Temp
- {
- get; set;
- }
- public string PumpingPinState
- {
- get; set;
- }
- public string VentingPinState
- {
- get; set;
- }
- public string PinDownPressure
- {
- get; set;
- }
- }
- public class EndPointConfigItem : INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
- public void InvokePropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- public string ExposureTime { get; set; }
- public string WaveLengthA { get; set; }
- public string BinningA { get; set; }
- public string WaveLengthB { get; set; }
- public string BinningB { get; set; }
- public string WaveLengthC { get; set; }
- public string BinningC { get; set; }
- public string WaveLengthD { get; set; }
- public string BinningD { get; set; }
- public string Fd { get; set; }
- public string PrefilterTime { get; set; }
- public string PostfilterTime { get; set; }
- public string AlgorithmType { get; set; }
- public string Criteria { get; set; }
- public string DelayTime { get; set; }
- public string ValidationTime { get; set; }
- public string ValidationValue { get; set; }
- public string TimeWindow { get; set; }
- public string MinimalTime { get; set; }
- public string PostponeTime { get; set; }
- public bool Control { get; set; }
- public bool Normalization { get; set; }
- public bool EnablePostponePercent { get; set; }
- public bool EnableCriterialPercent { get; set; }
- public bool EnableEventTrigger { get; set; }
- public bool IsFaultIfNoTrigger { get; set; }
- public string ToValue()
- {
- return
- $@"ExposureTime={ExposureTime};WaveLengthA={WaveLengthA};BinningA={BinningA};WaveLengthB={WaveLengthB};" +
- $@"BinningB={BinningB};WaveLengthC={WaveLengthC};BinningC={BinningC};WaveLengthD={WaveLengthD};BinningD={BinningD};Fd={Fd};" +
- $@"PrefilterTime={PrefilterTime};PostfilterTime={PostfilterTime};AlgorithmType={AlgorithmType};Criteria={Criteria};DelayTime={DelayTime};ValidationTime={ValidationTime};" +
- $@"ValidationValue={ValidationValue};TimeWindow={TimeWindow};MinimalTime={MinimalTime};PostponeTime={PostponeTime};Control={Control};Normalization={Normalization};" +
- $@"EnablePostponePercent={EnablePostponePercent};EnableCriterialPercent={EnableCriterialPercent};EnableEventTrigger={EnableEventTrigger};IsFaultIfNoTrigger={IsFaultIfNoTrigger};"
- ;
- }
- public void SetValue(string config)
- {
- if (string.IsNullOrEmpty(config))
- return;
- string[] items = config.Split(';');
- foreach (var item in items)
- {
- if (string.IsNullOrEmpty(item))
- continue;
- string[] pairs = item.Split('=');
- if (pairs.Length != 2)
- continue;
- Parallel.ForEach(this.GetType().GetProperties(),
- property =>
- {
- PropertyInfo pi = (PropertyInfo) property;
- if (pi.Name == pairs[0])
- {
- try
- {
- var convertedValue = Convert.ChangeType(pairs[1], pi.PropertyType);
- var originValue = Convert.ChangeType(pi.GetValue(this, null), pi.PropertyType);
- if (originValue != convertedValue)
- {
- pi.SetValue(this, convertedValue, null);
- }
- }
- catch (Exception)
- {
- }
- }
- });
- }
- }
- }
- }
|