| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468 | using Aitex.Core.RT.Log;using Caliburn.Micro.Core;using MECF.Framework.Common.CommonData;using MECF.Framework.Common.DataCenter;using MECF.Framework.Common.RecipeCenter;using MECF.Framework.Common.Utilities;using MECF.Framework.UI.Client.CenterViews.Configs.SystemConfig;using RecipeEditorLib.DGExtension.CustomColumn;using RecipeEditorLib.RecipeModel.Params;using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Reflection;using System.Text;using System.Windows;using System.Xml;using System.ComponentModel;using OpenSEMI.ClientBase;using MECF.Framework.UI.Client.ClientBase;namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe{    public class RecipeTable : PropertyChangedBase    {        private int _Index;        public int Index        {            get { return _Index; }            set { _Index = value; this.NotifyOfPropertyChange(nameof(Index)); }        }        private string _Name;        public string Name        {            get { return _Name; }            set { _Name = value; this.NotifyOfPropertyChange(nameof(Name)); }        }        private string _EndStatus;        public string EndStatus        {            get { return _EndStatus; }            set { _EndStatus = value; this.NotifyOfPropertyChange(nameof(EndStatus)); }        }        private RecipeDataBase _TableData;        public RecipeDataBase TableData        {            get { return _TableData; }            set { _TableData = value; this.NotifyOfPropertyChange(nameof(TableData)); }        }    }    public class RecipeDataBase : PropertyChangedBase    {        public static string[] SaveTableRecipeTypes = new string[] { "sub", "alarm", "abort" };        public static string ProcessType = "Process";        public bool GetIsTableType        {            get            {                if (string.IsNullOrEmpty(RecipeChamberType))                    return false;                else if (SaveTableRecipeTypes.Contains(RecipeChamberType))                {                    return true;                }                else                {                    return false;                }            }        }        public bool IsChanged        {            get            {                bool changed = !IsSavedDesc;                if (!changed)                {                    //changed = ChkChanged(Steps) || ChkChanged(PopSettingSteps) || ChkChanged(StepTolerances);                }                if (!changed)                {                    foreach (Param config in this.ConfigItems)                    {                        if (!config.IsSaved)                        {                            changed = true;                            break;                        }                    }                }                return changed;            }        }        private bool _isSavedDesc;        public bool IsSavedDesc        {            get { return _isSavedDesc; }            set            {                this._isSavedDesc = value;                this.NotifyOfPropertyChange("IsSavedDesc");            }        }        private string name;        public string Name        {            get { return this.name; }            set            {                this.name = value;                this.NotifyOfPropertyChange("Name");            }        }        private string _chamberType;        public string RecipeChamberType        {            get { return this._chamberType; }            set            {                this._chamberType = value;                CreateTable(value);                this.NotifyOfPropertyChange("RecipeChamberType");            }        }        public void CreateTable(string type)        {            if (SaveTableRecipeTypes.Contains(type))            {                int maxCount = 20;                if (type.ToLower() == "abort")                {                    maxCount = 10;                }                for (int i = 0; i < maxCount; i++)                {                    Tables.Add(new RecipeTable()                    { Index = i + 1, Name = "", EndStatus = "", TableData = new RecipeDataBase() });                }            }        }        private string _recipeVersion;        public string RecipeVersion        {            get { return this._recipeVersion; }            set            {                this._recipeVersion = value;                this.NotifyOfPropertyChange("RecipeVersion");            }        }        private string _recipePermission;        public string RecipePermission        {            get { return this._recipePermission; }            set            {                this._recipePermission = value;                this.NotifyOfPropertyChange("RecipePermisson");            }        }        private string _recipeLevel;        public string RecipeLevel        {            get { return this._recipeLevel; }            set            {                this._recipeLevel = value;                this.NotifyOfPropertyChange("RecipeLevel");            }        }        private string _prefixPath;        public string PrefixPath        {            get { return _prefixPath; }            set            {                _prefixPath = value;                this.NotifyOfPropertyChange("PrefixPath");            }        }        private string creator;        public string Creator        {            get { return this.creator; }            set            {                this.creator = value;                this.NotifyOfPropertyChange("Creator");            }        }        private DateTime createTime;        public DateTime CreateTime        {            get { return this.createTime; }            set            {                this.createTime = value;                this.NotifyOfPropertyChange("CreateTime");            }        }        private string description;        public string Description        {            get { return this.description; }            set            {                this.description = value;                this.NotifyOfPropertyChange("Description");            }        }        private string devisor;        public string Revisor        {            get { return this.devisor; }            set            {                this.devisor = value;                this.NotifyOfPropertyChange("Revisor");            }        }        private int _TableIndex = 1;        public int TableIndex        {            get { return this._TableIndex; }            set            {                this._TableIndex = value;                this.NotifyOfPropertyChange("TableIndex");            }        }        public string Time        {            get => GetTime();        }        private string GetTime()        {            var parm = this.ConfigItems.FirstOrDefault(x => x.Name == "RecipeTime") as StringParam;            if (parm != null)            {                return ConvertSecondsToHMSFormat(parm.Value);            }            return "00:00:00.0";        }        public static string ConvertSecondsToHMSFormat(string strTotalSeconds)        {            double totalSeconds = 0;            double.TryParse(strTotalSeconds, out totalSeconds);            int intTotalSeconds = (int)totalSeconds;            int hours = intTotalSeconds / 3600;            int minutes = (intTotalSeconds % 3600) / 60;            double seconds = intTotalSeconds % 60 + (totalSeconds - intTotalSeconds);            return string.Format("{0:00}:{1:00}:{2:00.0}", hours, minutes, seconds);        }        public string TableName => Tables.Count > 0 ? Tables.FirstOrDefault(x => x.Index == TableIndex).Name : "";        private DateTime deviseTime;        public DateTime ReviseTime        {            get { return this.deviseTime; }            set            {                this.deviseTime = value;                this.NotifyOfPropertyChange("ReviseTime");            }        }        public ObservableCollection<Step> Steps { get; set; }        public Dictionary<string, ObservableCollection<ObservableCollection<Param>>> PopSettingSteps { get; private set; }        public ObservableCollection<ObservableCollection<Param>> StepTolerances { get; private set; }        public ObservableCollection<Param> ConfigItems { get; private set; }        public List<int> StepNos { get; set; } = new List<int>();        private XmlDocument _doc;        private string _module = "PM1";        public bool ToleranceEnable { get; set; }        public Dictionary<string, bool> PopEnable { get; set; }        public bool IsCompatibleWithCurrentFormat { get; set; }        private RecipeProvider _recipeProvider = new RecipeProvider();        private Dictionary<string, ObservableCollection<RecipeTemplateColumnBase>> RecipeTemplate;        public ObservableCollection<RecipeTable> Tables { get; set; } = new ObservableCollection<RecipeTable>();        public void ShallowCopyStep(ref Step destinationStep, Step originalStep)        {            int stepNo = destinationStep.StepNo;            Type type = originalStep.GetType();            PropertyInfo[] properties = type.GetProperties();            // 遍历属性并赋值            foreach (PropertyInfo property in properties)            {                // 判断属性是否可写                if (property.CanWrite)                {                    // 设置属性的值                    property.SetValue(destinationStep, property.GetValue(originalStep));                }            }            destinationStep.StepNo = stepNo;        }        public void CloneStep(ref Step destinationStep, Step originalStep)        {            int stepNo = destinationStep.StepNo;            destinationStep = (Step)CloneUtil.CloneObjectSetFlag(originalStep, "IsSaved", true);            destinationStep.StepNo = stepNo;            SetDelegateEvent(destinationStep);            ////destinationStep.StepNo = originalStep.StepNo;            //destinationStep.Name = originalStep.Name;            //destinationStep.Time = originalStep.Time;            //destinationStep.SkipWait = originalStep.SkipWait;            //destinationStep.EndBy = originalStep.EndBy;            //destinationStep.MFCSets = originalStep.MFCSets;            //destinationStep.MFMSets = originalStep.MFMSets;            //destinationStep.ValveSets = originalStep.ValveSets;            ////destinationStep.AlarmActionSets = originalStep.AlarmActionSets;            //foreach (var temkey in originalStep.AlarmActionSets.Keys)            //{            //    if (!destinationStep.AlarmActionSets.ContainsKey(temkey))            //    {            //        destinationStep.AlarmActionSets.Add(temkey, originalStep.AlarmActionSets[temkey]);            //    }            //    else            //    {            //        destinationStep.AlarmActionSets[temkey] = originalStep.AlarmActionSets[temkey];            //    }            //}            //destinationStep.AlarmConditionTable = originalStep.AlarmConditionTable;            ////destinationStep.TemperatureSets = originalStep.TemperatureSets;            //foreach (var temkey in originalStep.TemperatureSets.Keys)            //{            //    if (!destinationStep.TemperatureSets.ContainsKey(temkey))            //    {            //        destinationStep.TemperatureSets.Add(temkey, originalStep.TemperatureSets[temkey]);            //    }            //    else            //    {            //        destinationStep.TemperatureSets[temkey] = originalStep.TemperatureSets[temkey];            //    }            //}            //destinationStep.TemperatureControlMode = originalStep.TemperatureControlMode;            //destinationStep.TemperatureCorrect = originalStep.TemperatureCorrect;            //destinationStep.TemperaturePID = originalStep.TemperaturePID;            //destinationStep.LoaderCommand = originalStep.LoaderCommand;            //destinationStep.LoaderValue = originalStep.LoaderValue;            //destinationStep.PressCommand = originalStep.PressCommand;            //destinationStep.PressValue = originalStep.PressValue;            //destinationStep.TemperatureProfile = originalStep.TemperatureProfile;            //destinationStep.TemperatureAlarm = originalStep.TemperatureAlarm;            //destinationStep.CAPTemperatureAlarm = originalStep.CAPTemperatureAlarm;            //destinationStep.CAPSetValue = originalStep.CAPSetValue;            //destinationStep.CAPRampingValue = originalStep.CAPRampingValue;            //destinationStep.TemperatureStabilize = originalStep.TemperatureStabilize;            //destinationStep.TemperatureReadyCond = originalStep.TemperatureReadyCond;            //destinationStep.RFSwitch = originalStep.RFSwitch;            //destinationStep.RFSetpoint = originalStep.RFSetpoint;            //destinationStep.RFPowerSetpoint = originalStep.RFPowerSetpoint;            //destinationStep.C1Setpoint = originalStep.C1Setpoint;            //destinationStep.C2Setpoint = originalStep.C2Setpoint;            //destinationStep.ForwardPowerAlarmWatchTable = originalStep.ForwardPowerAlarmWatchTable;            //destinationStep.PrAlarmWatchTable = originalStep.PrAlarmWatchTable;            //destinationStep.PIAlarmWatchTable = originalStep.PIAlarmWatchTable;            //destinationStep.C1AlarmWatchTable = originalStep.C1AlarmWatchTable;            //destinationStep.C2AlarmWatchTable = originalStep.C2AlarmWatchTable;            //destinationStep.VppAlarmWatchTable = originalStep.VppAlarmWatchTable;            //destinationStep.VdcAlarmWatchTable = originalStep.VdcAlarmWatchTable;            ////destinationStep.Command = originalStep.Command;            ////destinationStep.APC_SetPressure = originalStep.APC_SetPressure;            ////destinationStep.EXOUSets = originalStep.EXOUSets;            ////destinationStep.ExternalSensor = originalStep.ExternalSensor;            ////destinationStep.GasLineN2_Flow = originalStep.GasLineN2_Flow;            ////destinationStep.GasLineN3_Flow = originalStep.GasLineN3_Flow;            ////destinationStep.IsnoneConditionCheck = originalStep.IsnoneConditionCheck;            ////destinationStep.ZAxisPosition = originalStep.ZAxisPosition;            ////destinationStep.ZAxisSpeed = originalStep.ZAxisSpeed;            ////destinationStep.RotatePosition = originalStep.RotatePosition;            ////destinationStep.RotateSpeed = originalStep.RotateSpeed;            ////destinationStep.RotateInterval = originalStep.RotateInterval;            ////destinationStep.ReachPressureValue = originalStep.ReachPressureValue;            ////destinationStep.PressureStabilizeSelected = originalStep.PressureStabilizeSelected;            ////destinationStep.PressureSonserValue = originalStep.PressureSonserValue;            ////destinationStep.PressureValveAngle = originalStep.PressureValveAngle;            ////destinationStep.PressureSettingVG = originalStep.PressureSettingVG;            ////destinationStep.PressureAlarmTableNo = originalStep.PressureAlarmTableNo;            ////destinationStep.EventSetting = originalStep.EventSetting;            ////destinationStep.FinishAutoProfile = originalStep.FinishAutoProfile;            ////destinationStep.ReachTemp = originalStep.ReachTemp;            ////destinationStep.ReachPressure = originalStep.ReachPressure;            ////destinationStep.ReachPressureVG = originalStep.ReachPressureVG;            ////destinationStep.PressureStabilizeVG = originalStep.PressureStabilizeVG;            ////destinationStep.ReachTempValue = originalStep.ReachTempValue;            ////destinationStep.TempStabilizeSelected = originalStep.TempStabilizeSelected;        }        public void CloneStep(Step destinationStep, Step originalStep)        {            //destinationStep.StepNo = originalStep.StepNo;            //destinationStep.Name = originalStep.Name;            //destinationStep.EndBy = originalStep.EndBy;            //destinationStep.Time = originalStep.Time;            //destinationStep.SkipWait = originalStep.SkipWait;            //destinationStep.Command = originalStep.Command;            //destinationStep.APC_SetPressure = originalStep.APC_SetPressure;            //destinationStep.EXOUSets = originalStep.EXOUSets;            //destinationStep.ExternalSensor = originalStep.ExternalSensor;            //destinationStep.GasLineN2_Flow = originalStep.GasLineN2_Flow;            //destinationStep.GasLineN3_Flow = originalStep.GasLineN3_Flow;            //destinationStep.IsnoneConditionCheck = originalStep.IsnoneConditionCheck;            //destinationStep.ZAxisPosition = originalStep.ZAxisPosition;            //destinationStep.ZAxisSpeed = originalStep.ZAxisSpeed;            //destinationStep.RotatePosition = originalStep.RotatePosition;            //destinationStep.RotateSpeed = originalStep.RotateSpeed;            //destinationStep.RotateInterval = originalStep.RotateInterval;            //destinationStep.MFCSets = originalStep.MFCSets;            //destinationStep.MFMSets = originalStep.MFMSets;            //destinationStep.ValveSets = originalStep.ValveSets;            //destinationStep.ReachPressureValue = originalStep.ReachPressureValue;            //destinationStep.PressureStabilizeSelected = originalStep.PressureStabilizeSelected;            //destinationStep.PressureSonserValue = originalStep.PressureSonserValue;            //destinationStep.PressureValveAngle = originalStep.PressureValveAngle;            //destinationStep.PressureSettingVG = originalStep.PressureSettingVG;            //destinationStep.SlowVacuumValue = originalStep.SlowVacuumValue;            //destinationStep.PressureAlarmTableNo = originalStep.PressureAlarmTableNo;            //destinationStep.TemperatureCorrect = originalStep.TemperatureCorrect;            //destinationStep.TemperaturePID = originalStep.TemperaturePID;            //destinationStep.LoaderCommand = originalStep.LoaderCommand;            //destinationStep.LoaderValue = originalStep.LoaderValue;            //destinationStep.PressCommand = originalStep.PressCommand;            //destinationStep.PressValue = originalStep.PressValue;            //destinationStep.TemperatureSets = originalStep.TemperatureSets;            //destinationStep.EventSetting = originalStep.EventSetting;            //destinationStep.FinishAutoProfile = originalStep.FinishAutoProfile;            //destinationStep.ReachTemp = originalStep.ReachTemp;            //destinationStep.O2Density = originalStep.O2Density;            //destinationStep.ReachPressure = originalStep.ReachPressure;            //destinationStep.ReachPressureVG = originalStep.ReachPressureVG;            //destinationStep.PressureStabilizeVG = originalStep.PressureStabilizeVG;            //destinationStep.ReachTempValue = originalStep.ReachTempValue;            //destinationStep.O2DensityValue = originalStep.O2DensityValue;            //destinationStep.RotateDirection = originalStep.RotateDirection;            //destinationStep.TempStabilizeSelected = originalStep.TempStabilizeSelected;            destinationStep = (Step)CloneUtil.CloneObject(originalStep);            SetDelegateEvent(destinationStep);        }        public RecipeDataBase()        {            this.Steps = new ObservableCollection<Step>();            StepTolerances = new ObservableCollection<ObservableCollection<Param>>();            this.PopSettingSteps = new Dictionary<string, ObservableCollection<ObservableCollection<Param>>>();            this.PopEnable = new Dictionary<string, bool>();            ConfigItems = new ObservableCollection<Param>()            {                new StringParam { Name="Combination.SubRecipe"},                new StringParam { Name="Combination.AlarmRecipe"},                new StringParam { Name="Combination.AlarmCondition"},                new StringParam { Name="Combination.LeakCheck"},                new StringParam { Name="Combination.AbortRecipe"},                new StringParam { Name="Combination.PressAPCPID"},                new StringParam { Name="Combination.TempCorrection"},                new StringParam { Name="Combination.TempPID"},                new StringParam { Name="Combination.ProfileCondition"},                new StringParam { Name="RecipeTime"},            };            IsSavedDesc = true;            _doc = new XmlDocument();            XmlElement node = _doc.CreateElement("Aitex");            _doc.AppendChild(node);            node.AppendChild(_doc.CreateElement("TableRecipeData"));            string vars = _recipeProvider.GetRecipeFormatXml(MECF.Framework.Common.Equipment.ModuleName.PM1);            RecipeTemplate = _recipeProvider.GetGroupRecipeTemplate();            StepCollectionChanged();        }        private void StepCollectionChanged()        {            foreach (var item in Steps)            {                item.TempValueChangedEvent += Item_TempValueChangedEvent;                item.MFCValueChangedEvent += Item_MFCValueChangedEvent;                item.ValveValueChangedEvent += Item_ValveValueChangedEvent;                item.AUXValueChangedEvent += Item_AUXValueChangedEvent;                item.OhterTempValueChangedEvent += Item_OhterTempValueChangedEvent;                item.PressureValueChangedEvent += Item_PressureValueChangedEvent;                item.LoaderValueChangedEvent += Item_LoaderValueChangedEvent;                item.AlarmValueChangedEvent += Item_AlarmValueChangedEvent;            }            Steps.CollectionChanged += (s, e) =>            {                if (e.OldItems != null)                {                    foreach (Step item in e.OldItems)                    {                        item.TempValueChangedEvent -= Item_TempValueChangedEvent;                        item.MFCValueChangedEvent -= Item_MFCValueChangedEvent;                        item.ValveValueChangedEvent -= Item_ValveValueChangedEvent;                        item.AUXValueChangedEvent -= Item_AUXValueChangedEvent;                        item.OhterTempValueChangedEvent -= Item_OhterTempValueChangedEvent;                        item.PressureValueChangedEvent -= Item_PressureValueChangedEvent;                        item.LoaderValueChangedEvent -= Item_LoaderValueChangedEvent;                        item.AlarmValueChangedEvent -= Item_AlarmValueChangedEvent;                    }                }                if (e.NewItems != null)                {                    foreach (Step item in e.NewItems)                    {                        item.TempValueChangedEvent += Item_TempValueChangedEvent;                        item.MFCValueChangedEvent += Item_MFCValueChangedEvent;                        item.ValveValueChangedEvent += Item_ValveValueChangedEvent;                        item.AUXValueChangedEvent += Item_AUXValueChangedEvent;                        item.OhterTempValueChangedEvent += Item_OhterTempValueChangedEvent;                        item.PressureValueChangedEvent += Item_PressureValueChangedEvent;                        item.LoaderValueChangedEvent += Item_LoaderValueChangedEvent;                        item.AlarmValueChangedEvent += Item_AlarmValueChangedEvent;                    }                }            };        }        private void Item_LoaderValueChangedEvent(object sender, SetValueEventArgs e)        {            //throw new NotImplementedException();        }        private void Item_AlarmValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].AlarmConditionTable.IsSaved)                        {                            string tempName = e.ValueName;                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            Type type = Steps[i].GetType();                            PropertyInfo[] properties = type.GetProperties();                            var property = properties.FirstOrDefault(x => x.Name == proName);                            if (property != null)                            {                                var proParam = property.GetValue(Steps[i]);                                if (proParam is StringParam)                                {                                    ((StringParam)proParam).Value = proValue;                                    //property.SetValue(Steps[i], proParam);                                }                            }                        }                        else                        { break; }                    }                }            }        }        private void Item_PressureValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].PressIsSaved)                        {                            string tempName = e.ValueName;                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            Type type = Steps[i].GetType();                            PropertyInfo[] properties = type.GetProperties();                            var property = properties.FirstOrDefault(x => x.Name == proName);                            if (property != null)                            {                                var proParam = property.GetValue(Steps[i]);                                if (proParam is DoubleParam)                                {                                    ((DoubleParam)proParam).Value = proValue;                                    property.SetValue(Steps[i], proParam);                                }                                else if (proParam is StringParam)                                {                                    ((StringParam)proParam).Value = proValue;                                    property.SetValue(Steps[i], proParam);                                }                            }                        }                        else                        { break; }                    }                }            }        }        private void Item_OhterTempValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].TemperatureIsSaved)                        {                            string tempName = e.ValueName;                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            Type type = Steps[i].GetType();                            PropertyInfo[] properties = type.GetProperties();                            var property = properties.FirstOrDefault(x => x.Name == proName);                            if (property != null)                            {                                var proParam = property.GetValue(Steps[i]);                                if (proParam is DoubleParam)                                {                                    ((DoubleParam)proParam).Value = proValue;                                    property.SetValue(Steps[i], proParam);                                }                                else if (proParam is StringParam)                                {                                    ((StringParam)proParam).Value = proValue;                                    ((StringParam)proParam).IsSaved = true;                                    property.SetValue(Steps[i], proParam);                                }                                else if (proParam is BoolParam)                                {                                    bool tryValue = true;                                    bool.TryParse(proValue, out tryValue);                                    ((BoolParam)proParam).Value = tryValue;                                    property.SetValue(Steps[i], proParam);                                }                            }                        }                        else                        { break; }                    }                }            }        }        private void Item_MFCValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].MFCIsSaved)                        {                            var tempData = (MFCData)e.Sender;                            string tempName = e.ValueName;                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            var temp = Steps[i].MFCSets.FirstOrDefault(x => x.ControlName == tempName);                            Type type = temp.GetType();                            PropertyInfo[] properties = type.GetProperties();                            var property = properties.FirstOrDefault(x => x.Name == proName);                            if (property != null)                            {                                var proParam = property.GetValue(temp);                                if (proParam is DoubleParam)                                {                                    ((DoubleParam)proParam).Value = proValue;                                    property.SetValue(temp, proParam);                                }                                else if (proParam is IntParam)                                {                                    int.TryParse(proValue, out int outValue);                                    ((IntParam)proParam).Value = outValue;                                    property.SetValue(temp, proParam);                                }                                else if (proParam is StringParam)                                {                                    ((StringParam)proParam).Value = proValue;                                    property.SetValue(temp, proParam);                                }                                else if (proParam is BoolParam)                                {                                    bool tryValue = true;                                    bool.TryParse(proValue, out tryValue);                                    ((BoolParam)proParam).Value = tryValue;                                    property.SetValue(temp, proParam);                                }                            }                        }                        else                        { break; }                    }                }            }        }        private void Item_TempValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].TemperatureIsSaved)                        {                            var tempData = (TempSetData)e.Sender;                            string tempName = e.ValueName;                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            var temp = Steps[i].TemperatureSets.FirstOrDefault(x => x.Name == tempName);                            Type type = temp.GetType();                            PropertyInfo[] properties = type.GetProperties();                            var property = properties.FirstOrDefault(x => x.Name == proName);                            if (property != null)                            {                                var proParam = property.GetValue(temp);                                if (proParam is DoubleParam)                                {                                    ((DoubleParam)proParam).Value = proValue;                                    property.SetValue(temp, proParam);                                }                                else if (proParam is StringParam)                                {                                    ((StringParam)proParam).Value = proValue;                                    property.SetValue(temp, proParam);                                }                            }                        }                        else                        { break; }                    }                }            }        }        private void Item_TempOtherValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].TemperatureIsSaved)                        {                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            Type type = step.GetType();                            PropertyInfo[] properties = type.GetProperties();                            var property = properties.FirstOrDefault(x => x.Name == proName);                            if (property != null)                            {                                var proParam = property.GetValue(Steps[i]);                                if (proParam is StringParam)                                {                                    ((StringParam)proParam).Value = proValue;                                    property.SetValue(Steps[i], proParam);                                }                            }                        }                        else                        { break; }                    }                }            }        }        private void Item_AUXValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].AUXIsSaved)                        {                            var tempData = (AUXData)e.Sender;                            string tempName = e.ValueName;                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            var temp = Steps[i].AUXSets.FirstOrDefault(x => x.ControlName == tempName);                            Type type = temp.GetType();                            PropertyInfo[] properties = type.GetProperties();                            var property = properties.FirstOrDefault(x => x.Name == proName);                            if (property != null)                            {                                var proParam = property.GetValue(temp);                                if (proParam is DoubleParam)                                {                                    ((DoubleParam)proParam).Value = proValue;                                    property.SetValue(temp, proParam);                                }                                else if (proParam is StringParam)                                {                                    ((StringParam)proParam).Value = proValue;                                    property.SetValue(temp, proParam);                                }                                else if (proParam is BoolParam)                                {                                    bool tryValue = true;                                    bool.TryParse(proValue, out tryValue);                                    ((BoolParam)proParam).Value = tryValue;                                    property.SetValue(temp, proParam);                                }                            }                        }                        else                        { break; }                    }                }            }        }        private void Item_ValveValueChangedEvent(object sender, SetValueEventArgs e)        {            if (sender != null && sender is Step)            {                var step = sender as Step;                int stepIndex = Steps.IndexOf(step);                if (stepIndex < Steps.Count - 1)                {                    for (int i = stepIndex + 1; i < Steps.Count; i++)                    {                        if (Steps[i].ValveIsSaved)                        {                            var tempData = (BoolParam)e.Sender;                            string tempName = e.ValueName;                            string proName = e.PropertyName;                            string proValue = e.PropertyValue;                            var temp = Steps[i].ValveSets.FirstOrDefault(x => x.Name == tempData.Name);                            bool tempValue = false;                            bool.TryParse(proValue, out tempValue);                            temp.Value = tempValue;                        }                        else                        { break; }                    }                }            }        }        public void Clear()        {            Steps.Clear();            PopSettingSteps.Clear();            StepTolerances.Clear();            RecipeChamberType = "";            RecipeVersion = "";            IsSavedDesc = true;            _module = "PM1";        }        public void StepCloneChangedIndex()        {            int index = 1;            foreach (var item in Steps)            {                item.StepNo = index;                index += 1;            }        }        public void InitData(string prefixPath, string recipeName, string recipeContent, string module, int tableNo = 1)        {            IsCompatibleWithCurrentFormat = false;            _module = module;            Name = recipeName;            PrefixPath = prefixPath;            try            {                _doc = new XmlDocument();                _doc.LoadXml(recipeContent);                if (!LoadHeader(_doc.SelectSingleNode("Aitex/TableRecipeData")))                    return;                //Load Tables                XmlNode nodeTable = _doc.SelectSingleNode($"Aitex/TableRecipeData/Tables");                if (nodeTable != null)                    LoadTables(nodeTable);                if (!SaveTableRecipeTypes.Contains(RecipeChamberType))                {                    XmlNodeList nodeSteps = _doc.SelectNodes($"Aitex/TableRecipeData/Module[@Name='{module}']/Step");                    if (nodeSteps == null)                        nodeSteps = _doc.SelectNodes($"Aitex/TableRecipeData/Step");                    FastLoadSteps(nodeSteps);                    // LoadSteps(nodeSteps);                    XmlNode nodeConfig = _doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{module}']/Config");                    if (nodeConfig == null)                        nodeConfig = _doc.SelectSingleNode($"Aitex/TableRecipeData/Config");                    LoadConfigs(nodeConfig);                }                else                {                    Steps.Clear();                    StepNos.Clear();                    TableIndex = 1;                    Tables[0].TableData.Steps.ToList().ForEach(                        x =>                        {                            var tempStep = x;// (Step)CloneUtil.CloneObject(x);                            tempStep.StepNo = x.StepNo;                            Steps.Add(tempStep);                            StepNos.Add(x.StepNo);                        });                }                //var index = 1;                //foreach (Step parameters in Steps)                //{                //    parameters.Value = index.ToString();                //    index++;                //}                IsCompatibleWithCurrentFormat = true;            }            catch (Exception ex)            {                LOG.Write(ex);            }        }        public void SaveTo(string[] moduleList)        {            GetXmlString();            XmlNode nodeModule = _doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{_module}']");            if (nodeModule == null)            {                LOG.Write("recipe not find modules," + Name);                return;            }            XmlNode nodeData = nodeModule.ParentNode;            foreach (var module in moduleList)            {                if (module == _module)                {                    continue;                }                var child = _doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{module}']");                if (child != null)                    nodeData.RemoveChild(child);                XmlElement node = nodeModule.Clone() as XmlElement;                node.SetAttribute("Name", module);                nodeData.AppendChild(node);            }        }        int StepNo = 1;        public string DictionaryStepTime(Dictionary<string, string> steptimes)        {            if (steptimes == null && steptimes.Count == 0) return null;            StringBuilder rtn = new StringBuilder();            foreach (var item in steptimes.Keys)            {                if (steptimes[item] == "00:00:00") continue;                rtn.Append($"{item},{steptimes[item]};");            }            if (rtn.Length > 0) rtn.Remove(rtn.Length - 1, 1);            return rtn.ToString();        }        public Dictionary<string, string> StepTimeToDictionary(string stepTime)        {            Dictionary<string, string> steptimes = new Dictionary<string, string>();            string[] tempTimes = stepTime.Split(';');            foreach (var item in tempTimes)            {                string[] subTimes = item.Split(',');                steptimes.Add(subTimes[0], subTimes[1]);            }            return steptimes;        }        private List<string> valveDefaultOpen = new List<string>() { "AGV", "MBP", "DP", "HTR1", "HTR2", "HTR3" };        private MFCData GetNewMFCData(string controlName)        {            return new MFCData()            {                Name = controlName,                ControlName = controlName.Replace(".Flow", ""),                SetValue = new StringParam() { Name = "SetValue", Value = "0" },                SetUnit = new StringParam() { Name = "SetUnit", Value = "SLM" },                Rampng = new DoubleParam() { Name = "Rampng", Value = "0" },                RampngUnit = new StringParam() { Name = "RampngUnit", Value = "SLM" },                AlarmValue = "None",                IsCheck = new BoolParam() { Name = "IsCheck", Value = false },                MaxValue = new DoubleParam() { Name = "MaxValue", Value = "0" },                MinValue = new DoubleParam { Name = "MaxValue", Value = "0" }            };        }        public Step CreateStep(Step oldStep, XmlNode stepNode = null)        {            if (oldStep == null)            {                return CreateStep(stepNode);            }            else            {                Step step = (Step)CloneUtil.CloneObject(oldStep);                if (stepNode != null)                {                    if (stepNode.Attributes["StepNo"] != null)                        step.StepNo = int.Parse(stepNode.Attributes["StepNo"].Value);                    if (stepNode.Attributes["Name"] != null)                        step.Name = stepNode.Attributes["Name"].Value;                    if (stepNode.Attributes["EndBy"] != null)                        step.EndBy = stepNode.Attributes["EndBy"].Value;                    if (stepNode.Attributes["Time"] != null)                    {                        var timeValue = stepNode.Attributes["Time"].Value;                        if (!string.IsNullOrEmpty(timeValue) && !timeValue.Contains('.'))                        {                            timeValue = $"{timeValue}.0";                        }                        step.Time = timeValue;                    }                    if (stepNode.Attributes["SkipWait"] != null)                        step.SkipWait = stepNode.Attributes["SkipWait"].Value;                    else                        step.SkipWait = "";                    if (stepNode.Attributes["Command"] != null)                        step.Command = stepNode.Attributes["Command"].Value;                    AnalysisIsSaved(stepNode, step);                    ReadConditionCheck(stepNode, step);                    if (stepNode.Attributes["AlarmConditionTable"] != null)                        step.AlarmConditionTable = new StringParam() { Name = "AlarmConditionTable", Value = stepNode.Attributes["AlarmConditionTable"].Value };                    if (stepNode.Attributes["AbortRecipeTableIndex"] != null)                        step.AbortRecipeTableIndex = stepNode.Attributes["AbortRecipeTableIndex"].Value;                    if (stepNode.Attributes["FilmThickFormula"] != null)                        step.FilmThickFormula = stepNode.Attributes["FilmThickFormula"].Value;                    if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Valve"))                    {                        foreach (var item in RecipeTemplate["Valve"])                        {                            var _tempValve = step.ValveSets.FirstOrDefault(x => x.Name == item.ControlName);                            if (stepNode.Attributes[item.ControlName] != null && _tempValve != null)                            {                                var tempstr = stepNode.Attributes[item.ControlName].Value;                                //if (valveDefaultOpen.Contains(item.ControlName))                                //{                                //    _tempValve.Value = true;                                //}                                //else                                //{                                var boolVal = stepNode.Attributes[item.ControlName].Value == "Open" ? true : false;                                _tempValve.Value = boolVal;                                //}                            }                            else                            {                                if (valveDefaultOpen.Contains(item.ControlName))                                {                                    var findVal = step.ValveSets.FirstOrDefault(x => x.Name == item.ControlName);                                    if (findVal != null)                                    {                                        findVal.Value = true;                                    }                                    else                                    {                                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = true });                                    }                                }                                else                                {                                    var findVal = step.ValveSets.FirstOrDefault(x => x.Name == item.ControlName);                                    if (findVal != null)                                    {                                        findVal.Value = false;                                    }                                    else                                    {                                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = false });                                    }                                }                            }                        }                    }                    if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Temperature"))                    {                        foreach (var item in RecipeTemplate["Temperature"])                        {                            FromXmlNodeGetTemperatureSets(stepNode, step, item);                        }                    }                    if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFC"))                    {                        foreach (var item in RecipeTemplate["MFC"])                        {                            var mFCData = step.MFCSets.FirstOrDefault(x => x.ControlName == item.ControlName.Replace(".Flow", ""));                            if (mFCData == null)                            {                                step.MFCSets.Add(GetNewMFCData(item.ControlName));                            }                            if (step.MFCSets != null && step.MFCSets.Count > 0)                            {                                for (int i = 0; i < step.MFCSets.Count; i++)                                {                                    step.MFCSets[i].No = i + 1;                                }                            }                            if (stepNode.Attributes[$"{item.ControlName}.IsSaved"] != null)                            {                                bool.TryParse(stepNode.Attributes[$"{item.ControlName}.IsSaved"].Value, out bool isSaved);                                mFCData.FlagIsSaved = isSaved;                            }                            else                            {                                mFCData.FlagIsSaved = true;                            }                            var setValue = stepNode.Attributes[$"{item.ControlName}.Set"] != null ? stepNode.Attributes[$"{item.ControlName}.Set"].Value : "0";                            mFCData.SetValue = new StringParam() { Name = "SetValue", Value = setValue };                            var strSetUnit = stepNode.Attributes[$"{item.ControlName}.SetUnit"] != null ? stepNode.Attributes[$"{item.ControlName}.SetUnit"].Value : "SLM";                            mFCData.SetUnit = new StringParam() { Name = "SetUnit", Value = strSetUnit };                            var rampngValue = stepNode.Attributes[$"{item.ControlName}.Ramprate"] != null ? stepNode.Attributes[$"{item.ControlName}.Ramprate"].Value : "0";                            mFCData.Rampng = new DoubleParam() { Name = "Rampng", Value = rampngValue };                            var strRampngUnit = stepNode.Attributes[$"{item.ControlName}.RamprateUnit"] != null ? stepNode.Attributes[$"{item.ControlName}.RamprateUnit"].Value : "SLM";                            mFCData.RampngUnit = new StringParam() { Name = "RampngUnit", Value = strRampngUnit };                            var boolIsCheck = stepNode.Attributes[$"{item.ControlName}.Check"] != null ? bool.Parse(stepNode.Attributes[$"{item.ControlName}.Check"].Value) : false;                            mFCData.IsCheck = new BoolParam() { Name = "IsCheck", Value = boolIsCheck };                            double max = 0;                            if (stepNode.Attributes[$"{item.ControlName}.High"] != null && !string.IsNullOrEmpty(stepNode.Attributes[$"{item.ControlName}.High"].Value))                            {                                double.TryParse(stepNode.Attributes[$"{item.ControlName}.High"].Value, out max);                            }                            mFCData.MaxValue = new DoubleParam() { Name = "MaxValue", Value = max.ToString() };                            double min = 0;                            if (stepNode.Attributes[$"{item.ControlName}.Low"] != null && !string.IsNullOrEmpty(stepNode.Attributes[$"{item.ControlName}.Low"].Value))                            {                                double.TryParse(stepNode.Attributes[$"{item.ControlName}.Low"].Value, out min);                            }                            mFCData.MinValue = new DoubleParam() { Name = "MinValue", Value = min.ToString() };                            mFCData.Unit = stepNode.Attributes[$"{item.ControlName}.Unit"] != null ? stepNode.Attributes[$"{item.ControlName}.Unit"].Value : "SLM";                        }                    }                    if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFM"))                    {                        step.MFMSets.Clear();                        foreach (var item in RecipeTemplate["MFM"])                        {                            if (stepNode.Attributes[item.ControlName] != null)                            {                                var MFMListValues = stepNode.Attributes[item.ControlName].Value.Split(';');                                step.MFMSets.Add(item.ControlName, new MFMValue() { Value = MFMListValues[0] });                                if (MFMListValues.Length > 1 && RecipeTemplate != null && RecipeTemplate.ContainsKey("MFMAlarm"))                                {                                    step.MFMSets[item.ControlName].AlarmValue = MFMListValues[1];                                }                                else                                {                                    step.MFMSets.Add(item.ControlName, new MFMValue() { Value = "0", AlarmValue = "None" });                                }                            }                            else                            {                                if (!step.MFMSets.ContainsKey(item.ControlName))                                {                                    step.MFMSets.Add(item.ControlName, new MFMValue() { Value = "0", AlarmValue = "None" });                                }                            }                        }                    }                    for (int i = 1; i < 7; i++)                    {                        if (stepNode.Attributes[$"External.Out{i}"] != null && stepNode.Attributes[$"External.Out{i}"].Value != "")                        {                            if (step.EXOUSets.ContainsKey($"External.Out{i}"))                            {                                step.EXOUSets[$"External.Out{i}"] = bool.Parse(stepNode.Attributes[$"External.Out{i}"].Value);                            }                            else                            {                                step.EXOUSets.Add($"External.Out{i}", bool.Parse(stepNode.Attributes[$"External.Out{i}"].Value));                            }                        }                        else                        {                            if (!step.EXOUSets.ContainsKey($"External.Out{i}"))                            {                                step.EXOUSets.Add($"External.Out{i}", false);                            }                        }                    }                    if (stepNode.Attributes["Temperature.ControlMode"] != null)                        step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = stepNode.Attributes["Temperature.ControlMode"].Value };                    else                        step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = "Heater" };                    if (stepNode.Attributes["Temperature.Correct"] != null)                        step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = stepNode.Attributes["Temperature.Correct"].Value };                    else                        step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = "1" };                    if (stepNode.Attributes["Temperature.PID"] != null)                        step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = stepNode.Attributes["Temperature.PID"].Value };                    else                        step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = "1" };                    if (stepNode.Attributes["Loader.Command"] != null)                        step.LoaderCommand = new StringParam() { Name = "LoaderCommand", Value = stepNode.Attributes["Loader.Command"].Value };                    else                        step.LoaderCommand = new StringParam() { Name = "LoaderCommand", Value = "None" };                    if (stepNode.Attributes["Loader.Speed1"] != null)                    {                        step.LoaderSpeed1 = new DoubleParam() { Name = "LoaderSpeed1", Value = stepNode.Attributes["Loader.Speed1"].Value };                    }                    if (stepNode.Attributes["Loader.Speed2"] != null)                    {                        step.LoaderSpeed2 = new DoubleParam() { Name = "LoaderSpeed2", Value = stepNode.Attributes["Loader.Speed2"].Value };                    }                    if (stepNode.Attributes["Loader.Speed3"] != null)                    {                        step.LoaderSpeed3 = new DoubleParam() { Name = "LoaderSpeed3", Value = stepNode.Attributes["Loader.Speed3"].Value };                    }                    if (stepNode.Attributes["Loader.RPM"] != null)                    {                        step.LoaderRPM = new DoubleParam() { Name = "LoaderRPM", Value = stepNode.Attributes["Loader.RPM"].Value };                    }                    if (stepNode.Attributes["Press.Command"] != null)                        step.PressCommand = new StringParam() { Name = "PressCommand", Value = stepNode.Attributes["Press.Command"].Value };                    else                        step.PressCommand = new StringParam() { Name = "PressCommand", Value = "None" };                    if (stepNode.Attributes["Press.PID"] != null)                        step.PressPID = new StringParam() { Name = "PressPID", Value = stepNode.Attributes["Press.PID"].Value };                    if (stepNode.Attributes["Press.Set"] != null)                    {                        step.PressSet = new DoubleParam() { Name = "PressSet", Value = stepNode.Attributes["Press.Set"].Value };                    }                    if (stepNode.Attributes["Press.SlowVacSet"] != null)                    {                        step.PressSlowVacSet = new DoubleParam() { Name = "PressSlowVacSet", Value = stepNode.Attributes["Press.SlowVacSet"].Value };                    }                    if (stepNode.Attributes["Press.ValveAngleSet"] != null)                        step.PressValveAngleSet = new StringParam() { Name = "PressValveAngleSet", Value = stepNode.Attributes["Press.ValveAngleSet"].Value };                    if (stepNode.Attributes["Press.IsWait"] != null)                    {                        bool.TryParse(stepNode.Attributes["Press.IsWait"].Value, out bool isWait);                        step.PressIsWait = new BoolParam() { Name = "PressIsWait", Value = isWait };                    }                    if (stepNode.Attributes["Press.LowWait"] != null)                        step.PressLowWait = new StringParam() { Name = "PressLowWait", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.LowWait"].Value) ? stepNode.Attributes["Press.LowWait"].Value : "0" };                    if (stepNode.Attributes["Press.HighWait"] != null)                        step.PressHighWait = new StringParam() { Name = "PressHighWait", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.HighWait"].Value) ? stepNode.Attributes["Press.HighWait"].Value : "0" };                    if (stepNode.Attributes["Press.WaitUnit"] != null)                    {                        step.PressWaitUnit = new StringParam() { Name = "PressWaitUnit", Value = stepNode.Attributes["Press.WaitUnit"].Value };                    }                    if (stepNode.Attributes["Press.LowPressWait"] != null)                        step.PressLowPressWait = new StringParam() { Name = "PressLowPressWait", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.LowPressWait"].Value) ? stepNode.Attributes["Press.LowPressWait"].Value : "None" };                    if (stepNode.Attributes["Press.WaitPress"] != null)                        step.WaitPress = new StringParam() { Name = "PressLowPressWait", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.WaitPress"].Value) ? stepNode.Attributes["Press.WaitPress"].Value : "0" };                    if (RecipeTemplate != null && RecipeTemplate.ContainsKey("AUX"))                    {                        List<string> queryList = new List<string>();                        foreach (var item in RecipeTemplate["AUX"])                        {                            queryList.Add($"PM1.RecipeEditParameter.AUX.{item.ControlName}.Display");                            queryList.Add($"PM1.RecipeEditParameter.AUX.{item.ControlName}.Unit");                        }                        var dictValues = QueryDataClient.Instance.Service.PollConfig(queryList);                        foreach (var item in RecipeTemplate["AUX"])                        {                            if (stepNode.Attributes[$"AUX.{item.ControlName}.Set"] != null)                            {                                AUXData aUXData = step.AUXSets.FirstOrDefault(x => x.ControlName == item.ControlName);                                if (aUXData == null)                                {                                    aUXData = new AUXData();                                    var displayName = (string)dictValues[$"PM1.RecipeEditParameter.AUX.{item.ControlName}.Display"];                                    var auxUnit = (string)dictValues[$"PM1.RecipeEditParameter.AUX.{item.ControlName}.Unit"];                                    aUXData.ControlName = item.ControlName;                                    aUXData.DisplayName = displayName;                                    aUXData.Unit = auxUnit;                                }                                float setValue = 0;                                if (stepNode.Attributes[$"AUX.{item.ControlName}.Set"] != null)                                {                                    float.TryParse(stepNode.Attributes[$"AUX.{item.ControlName}.Set"].Value, out setValue);                                }                                aUXData.SetValue = new DoubleParam() { Name = "SetValue", Value = setValue.ToString() };                                var _ischeck = stepNode.Attributes[$"AUX.{item.ControlName}.Check"] != null ? bool.Parse(stepNode.Attributes[$"AUX.{item.ControlName}.Check"].Value) : false;                                aUXData.IsCheck = new BoolParam() { Name = "IsCheck", Value = _ischeck };                                float maxValue = 0;                                if (stepNode.Attributes[$"AUX.{item.ControlName}.High"] != null)                                {                                    float.TryParse(stepNode.Attributes[$"AUX.{item.ControlName}.High"].Value, out maxValue);                                }                                aUXData.MaxValue = new DoubleParam() { Name = "MaxValue", Value = maxValue.ToString() };                                float minValue = 0;                                if (stepNode.Attributes[$"AUX.{item.ControlName}.Low"] != null)                                {                                    float.TryParse(stepNode.Attributes[$"AUX.{item.ControlName}.Low"].Value, out minValue);                                }                                aUXData.MinValue = new DoubleParam() { Name = "MinValue", Value = minValue.ToString() };                                var _setunit = stepNode.Attributes[$"AUX.{item.ControlName}.CheckUnit"] != null ? stepNode.Attributes[$"AUX.{item.ControlName}.CheckUnit"].Value : "℃";                                aUXData.SetUnit = new StringParam() { Name = "SetUnit", Value = _setunit };                                if (step.AUXSets.Where(x => x.Name == item.ControlName).Any())                                {                                    step.AUXSets.Add(aUXData);                                }                            }                            else                            {                                var displayName = (string)dictValues[$"PM1.RecipeEditParameter.AUX.{item.ControlName}.Display"];                                var auxUnit = (string)dictValues[$"PM1.RecipeEditParameter.AUX.{item.ControlName}.Unit"];                                if (step.AUXSets.Where(x => x.Name == item.ControlName).Any())                                {                                    AddNewAUX(step, item, displayName, auxUnit);                                }                            }                        }                    }                }                SetDelegateEvent(step);                return step;            }        }        public void SetDelegateEvent(Step step)        {            MFCSetsCollectionChanged(step);            TemperatureSetsCollectionChanged(step);            ValveSetsCollectionChanged(step);            AUXSetsCollectionChanged(step);        }        private void MFCSetsCollectionChanged(Step step)        {            foreach (var item in step.MFCSets)            {                item.PropertyChanged += step.MFCIsSaved_PropertyChanged;                item.ValueChangedEvent += step.Item_MFCValueChangedEvent;            }        }        private void TemperatureSetsCollectionChanged(Step step)        {            foreach (var item in step.TemperatureSets)            {                item.PropertyChanged += step.TemperatureIsSaved_PropertyChanged;                item.ValueChangedEvent += step.Item_TempValueChangedEvent;            }        }        private void ValveSetsCollectionChanged(Step step)        {            foreach (var item in step.ValveSets)            {                item.PropertyChanged += step.ValveIsSaved_PropertyChanged;                item.ValueChangedEvent += step.Item_ValveValueChangedEvent;            }            //step.ValveSets.CollectionChanged += (s, e) =>            //{            //    if (e.OldItems != null)            //    {            //        foreach (BoolParam item in e.OldItems)            //        {            //            item.PropertyChanged -= step.ValveIsSaved_PropertyChanged;            //            item.ValueChangedEvent -= step.Item_ValveValueChangedEvent;            //        }            //    }            //    if (e.NewItems != null)            //    {            //        foreach (BoolParam item in e.NewItems)            //        {            //            item.PropertyChanged += step.ValveIsSaved_PropertyChanged;            //            item.ValueChangedEvent += step.Item_ValveValueChangedEvent;            //        }            //    }            //};        }        private void AUXSetsCollectionChanged(Step step)        {            foreach (var item in step.AUXSets)            {                item.PropertyChanged += step.AUXIsSaved_PropertyChanged;                item.ValueChangedEvent += step.Item_AUXValueChangedEvent;            }            //step.AUXSets.CollectionChanged += (s, e) =>            //{            //    if (e.OldItems != null)            //    {            //        foreach (AUXData item in e.OldItems)            //        {            //            item.PropertyChanged -= step.AUXIsSaved_PropertyChanged;            //            item.ValueChangedEvent -= step.Item_AUXValueChangedEvent;            //        }            //    }            //    if (e.NewItems != null)            //    {            //        foreach (AUXData item in e.NewItems)            //        {            //            item.PropertyChanged += step.AUXIsSaved_PropertyChanged;            //            item.ValueChangedEvent += step.Item_AUXValueChangedEvent;            //        }            //    }            //};        }        private static void AddNewAUX(Step step, RecipeTemplateColumnBase item, string displayName, string auxUnit)        {            var tempAUX = new AUXData()            {                ControlName = item.ControlName,                DisplayName = displayName,                SetValue = new DoubleParam() { Name = "SetValue", Value = "0" },                SetUnit = new StringParam() { Name = "SetUnit", Value = auxUnit },                Rampng = new DoubleParam() { Name = "Rampng", Value = "0" },                RampngUnit = new StringParam() { Name = "RampngUnit", Value = "SLM" },                AlarmValue = "None",                IsCheck = new BoolParam() { Name = "IsCheck", Value = false },                MaxValue = new DoubleParam() { Name = "MaxValue", Value = "0" },                MinValue = new DoubleParam() { Name = "MinValue", Value = "0" },                Unit = auxUnit            };            step.AUXSets.Add(tempAUX);        }        public Step CreateStep(XmlNode stepNode = null)        {            Step step = new Step();            if (stepNode != null)            {                if (stepNode.Attributes["StepNo"] != null)                    step.StepNo = int.Parse(stepNode.Attributes["StepNo"].Value);                if (stepNode.Attributes["Name"] != null)                    step.Name = stepNode.Attributes["Name"].Value;                if (stepNode.Attributes["EndBy"] != null)                    step.EndBy = stepNode.Attributes["EndBy"].Value;                if (stepNode.Attributes["Time"] != null)                {                    if (stepNode.Attributes["Time"] != null)                    {                        var timeValue = stepNode.Attributes["Time"].Value;                        if (!string.IsNullOrEmpty(timeValue) && !timeValue.Contains('.'))                        {                            timeValue = $"{timeValue}.0";                        }                        step.Time = timeValue;                    }                }                if (stepNode.Attributes["SkipWait"] != null)                    step.SkipWait = stepNode.Attributes["SkipWait"].Value;                else                    step.SkipWait = "";                if (stepNode.Attributes["Command"] != null)                    step.Command = stepNode.Attributes["Command"].Value;                AnalysisIsSaved(stepNode, step);                ReadConditionCheck(stepNode, step);                if (stepNode.Attributes["AbortRecipeTableIndex"] != null)                    step.AbortRecipeTableIndex = stepNode.Attributes["AbortRecipeTableIndex"].Value;                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Valve"))                {                    step.ValveSets.Clear();                    foreach (var item in RecipeTemplate["Valve"])                    {                        if (stepNode.Attributes[item.ControlName] != null)                        {                            var valValue = stepNode.Attributes[item.ControlName].Value == "Open" ? true : false;                            step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = valValue });                        }                        else                        {                            if (valveDefaultOpen.Contains(item.ControlName))                            {                                step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = true });                            }                            else                            {                                step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = false });                            }                        }                    }                }                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Temperature"))                {                    step.TemperatureSets.Clear();                    foreach (var item in RecipeTemplate["Temperature"])                    {                        FromXmlNodeGetTemperatureSets(stepNode, step, item);                    }                }                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFC"))                {                    step.MFCSets.Clear();                    foreach (var item in RecipeTemplate["MFC"])                    {                        if (stepNode.Attributes[$"{item.ControlName}.Set"] != null)                        {                            step.MFCSets.Add(StepNodeToMFCData(stepNode, item));                        }                        else                        {                            step.MFCSets.Add(GetNewMFCData(item.ControlName));                        }                    }                    if (step.MFCSets != null && step.MFCSets.Count > 0)                    {                        for (int i = 0; i < step.MFCSets.Count; i++)                        {                            step.MFCSets[i].No = i + 1;                        }                    }                }                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFM"))                {                    step.MFMSets.Clear();                    foreach (var item in RecipeTemplate["MFM"])                    {                        if (stepNode.Attributes[item.ControlName] != null)                        {                            var MFMListValues = stepNode.Attributes[item.ControlName].Value.Split(';');                            step.MFMSets.Add(item.ControlName, new MFMValue() { Value = MFMListValues[0] });                            if (MFMListValues.Length > 1 && RecipeTemplate != null && RecipeTemplate.ContainsKey("MFMAlarm"))                            {                                step.MFMSets[item.ControlName].AlarmValue = MFMListValues[1];                            }                        }                        else                        {                            step.MFMSets.Add(item.ControlName, new MFMValue() { Value = "0", AlarmValue = "None" });                        }                    }                }                for (int i = 1; i < 7; i++)                {                    if (stepNode.Attributes[$"External.Out{i}"] != null && stepNode.Attributes[$"External.Out{i}"].Value != "")                    {                        step.EXOUSets.Add($"External.Out{i}", bool.Parse(stepNode.Attributes[$"External.Out{i}"].Value));                    }                    else                    {                        step.EXOUSets.Add($"External.Out{i}", false);                    }                }                if (stepNode.Attributes["AlarmConditionTable"] != null)                    step.AlarmConditionTable = new StringParam() { Name = "AlarmConditionTable", Value = stepNode.Attributes["AlarmConditionTable"].Value };                if (stepNode.Attributes["Temperature.ControlMode"] != null)                    step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = stepNode.Attributes["Temperature.ControlMode"].Value };                else                    step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = "Heater" };                if (stepNode.Attributes["Temperature.Correct"] != null)                    step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = stepNode.Attributes["Temperature.Correct"].Value };                else                    step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = "1" };                if (stepNode.Attributes["Temperature.PID"] != null)                    step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = stepNode.Attributes["Temperature.PID"].Value };                else                    step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = "1" };                if (stepNode.Attributes["Loader.Command"] != null)                    step.LoaderCommand = new StringParam() { Name = "LoaderCommand", Value = stepNode.Attributes["Loader.Command"].Value };                else                    step.LoaderCommand = new StringParam() { Name = "LoaderCommand", Value = "None" };                if (stepNode.Attributes["Loader.Speed1"] != null)                {                    step.LoaderSpeed1 = new DoubleParam() { Name = "LoaderSpeed1", Value = stepNode.Attributes["Loader.Speed1"].Value };                }                if (stepNode.Attributes["Loader.Speed2"] != null)                {                    step.LoaderSpeed2 = new DoubleParam() { Name = "LoaderSpeed2", Value = stepNode.Attributes["Loader.Speed2"].Value };                }                if (stepNode.Attributes["Loader.Speed3"] != null)                {                    step.LoaderSpeed3 = new DoubleParam() { Name = "LoaderSpeed3", Value = stepNode.Attributes["Loader.Speed3"].Value };                }                if (stepNode.Attributes["Loader.RPM"] != null)                {                    step.LoaderRPM = new DoubleParam() { Name = "LoaderRPM", Value = stepNode.Attributes["Loader.RPM"].Value };                }                if (stepNode.Attributes["Press.Command"] != null)                    step.PressCommand = new StringParam() { Name = "PressCommand", Value = stepNode.Attributes["Press.Command"].Value };                else                    step.PressCommand = new StringParam() { Name = "PressCommand", Value = "None" };                if (stepNode.Attributes["Press.PID"] != null)                    step.PressPID = new StringParam() { Name = "PressPID", Value = stepNode.Attributes["Press.PID"].Value };                if (stepNode.Attributes["Press.Set"] != null)                {                    step.PressSet = new DoubleParam() { Name = "PressSet", Value = stepNode.Attributes["Press.Set"].Value };                }                if (stepNode.Attributes["Press.SlowVacSet"] != null)                {                    step.PressSlowVacSet = new DoubleParam() { Name = "PressSet", Value = stepNode.Attributes["Press.SlowVacSet"].Value };                }                if (stepNode.Attributes["Press.ValveAngleSet"] != null)                    step.PressValveAngleSet = new StringParam() { Name = "PressValveAngleSet", Value = stepNode.Attributes["Press.ValveAngleSet"].Value };                if (stepNode.Attributes["Press.IsWait"] != null)                {                    bool.TryParse(stepNode.Attributes["Press.IsWait"].Value, out bool isWait);                    step.PressIsWait = new BoolParam() { Name = "PressIsWait", Value = isWait };                }                if (stepNode.Attributes["Press.LowWait"] != null)                    step.PressLowWait = new StringParam() { Name = "PressLowWait", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.LowWait"].Value) ? stepNode.Attributes["Press.LowWait"].Value : "0" };                if (stepNode.Attributes["Press.HighWait"] != null)                    step.PressHighWait = new StringParam() { Name = "PressHighWait", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.HighWait"].Value) ? stepNode.Attributes["Press.HighWait"].Value : "0" };                if (stepNode.Attributes["Press.WaitUnit"] != null)                {                    step.PressWaitUnit = new StringParam() { Name = "PressWaitUnit", Value = stepNode.Attributes["Press.WaitUnit"].Value };                }                if (stepNode.Attributes["Press.LowPressWait"] != null)                    step.PressLowPressWait = new StringParam() { Name = "PressLowPressWait", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.LowPressWait"].Value) ? stepNode.Attributes["Press.LowPressWait"].Value : "None" };                if (stepNode.Attributes["Press.WaitPress"] != null)                    step.WaitPress = new StringParam() { Name = "WaitPress", Value = !string.IsNullOrEmpty(stepNode.Attributes["Press.WaitPress"].Value) ? stepNode.Attributes["Press.WaitPress"].Value : "0" };                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("AUX"))                {                    step.AUXSets.Clear();                    foreach (var item in RecipeTemplate["AUX"])                    {                        var displayName = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.RecipeEditParameter.AUX.{item.ControlName}.Display");                        var auxUnit = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.RecipeEditParameter.AUX.{item.ControlName}.Unit");                        if (stepNode.Attributes[$"AUX.{item.ControlName}.Set"] != null)                        {                            AUXData aUXData = new AUXData();                            aUXData.ControlName = item.ControlName;                            aUXData.DisplayName = displayName;                            aUXData.Unit = auxUnit;                            float setValue = 0;                            if (stepNode.Attributes[$"AUX.{item.ControlName}.Set"] != null)                            {                                float.TryParse(stepNode.Attributes[$"AUX.{item.ControlName}.Set"].Value, out setValue);                            }                            aUXData.SetValue = new DoubleParam() { Name = "SetValue", Value = setValue.ToString() };                            aUXData.IsCheck = new BoolParam() { Name = "IsCheck", Value = stepNode.Attributes[$"AUX.{item.ControlName}.Check"] != null ? bool.Parse(stepNode.Attributes[$"AUX.{item.ControlName}.Check"].Value) : false };                            float maxValue = 0;                            if (stepNode.Attributes[$"AUX.{item.ControlName}.High"] != null)                            {                                float.TryParse(stepNode.Attributes[$"AUX.{item.ControlName}.High"].Value, out maxValue);                            }                            aUXData.MaxValue = new DoubleParam() { Name = "MaxValue", Value = maxValue.ToString() };                            float minValue = 0;                            if (stepNode.Attributes[$"AUX.{item.ControlName}.Low"] != null)                            {                                float.TryParse(stepNode.Attributes[$"AUX.{item.ControlName}.Low"].Value, out minValue);                            }                            aUXData.MinValue = new DoubleParam() { Name = "MinValue", Value = minValue.ToString() };                            aUXData.SetUnit = new StringParam() { Name = "SetUnit", Value = stepNode.Attributes[$"AUX.{item.ControlName}.CheckUnit"] != null ? stepNode.Attributes[$"AUX.{item.ControlName}.CheckUnit"].Value : "℃" };                            step.AUXSets.Add(aUXData);                        }                        else                        {                            AddNewAUX(step, item, displayName, auxUnit);                        }                    }                }                if (stepNode.Attributes["AbortRecipeTableIndex"] != null)                    step.AbortRecipeTableIndex = stepNode.Attributes["AbortRecipeTableIndex"].Value;                else                    step.AbortRecipeTableIndex = "None";                for (int i = 1; i < 11; i++)                {                    string tempType = "";                    string tempDetails = "";                    if (stepNode.Attributes[$"AlarmAction.{i}"] != null && stepNode.Attributes[$"AlarmAction.{i}"].Value != "")                    {                        tempType = stepNode.Attributes[$"AlarmAction.{i}"].Value;                    }                    else                    {                        tempType = "Ignore Alarm";                    }                    if (stepNode.Attributes[$"AlarmDetails.{i}"] != null)                        tempDetails = stepNode.Attributes[$"AlarmDetails.{i}"].Value;                    step.AlarmActionSets.Add(i, new AlarmAction()                    {                        PtocessingType = tempType,                        PtocessingDetails = tempDetails                    });                }                if (stepNode.Attributes["FilmThickFormula"] != null)                    step.FilmThickFormula = stepNode.Attributes["FilmThickFormula"].Value;            }            else            {                step.StepNo = StepNo;                step.Name = "Name" + StepNo.ToString();                step.EndBy = "EndByStepTime";                step.Time = null;                step.SkipWait = "";                step.Command = "NoControl";                step.IsnoneConditionCheck = true;                step.AlarmConditionTable = new StringParam() { Name = "AlarmConditionTable", Value = "1:" };                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Valve"))                {                    step.ValveSets.Clear();                    foreach (var item in RecipeTemplate["Valve"])                    {                        if (valveDefaultOpen.Contains(item.ControlName))                        {                            step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = true });                        }                        else                        {                            step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = false });                        }                    }                }                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Temperature"))                {                    step.TemperatureSets.Clear();                    foreach (var item in RecipeTemplate["Temperature"])                    {                        var configHeater = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.Heater.{item.ControlName}.DisplayName");                        var tempSetData = new TempSetData(configHeater);                        tempSetData.Name = item.ControlName;                        tempSetData.DisplayName = configHeater;                        step.TemperatureSets.Add(tempSetData);                    }                }                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFC"))                {                    step.MFCSets.Clear();                    foreach (var item in RecipeTemplate["MFC"])                    {                        step.MFCSets.Add(GetNewMFCData(item.ControlName)); ;                    }                    if (step.MFCSets != null && step.MFCSets.Count > 0)                    {                        for (int i = 0; i < step.MFCSets.Count; i++)                        {                            step.MFCSets[i].No = i + 1;                        }                    }                }                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFM"))                {                    step.MFMSets.Clear();                    foreach (var item in RecipeTemplate["MFM"])                    {                        step.MFMSets.Add(item.ControlName, new MFMValue() { Value = "0", AlarmValue = "None" }); ;                    }                }                        step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = "Heater" };                step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = "" };                step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = "" };                step.LoaderCommand = new StringParam() { Name = "Loader", Value = "None" };                step.PressCommand = new StringParam() { Name = "PressCommand", Value = "None" };                step.FilmThickFormula = "";                step.AbortRecipeTableIndex = "None";                step.FinishAutoProfile = "None";                step.ReachPressure = "None";                step.ReachTemp = "None";                step.O2Density = "None";                step.TempStabilizeSelected = "None";                step.PressureStabilizeSelected = "None";                step.ProcessTimeToEnd = "None";                if (RecipeTemplate != null && RecipeTemplate.ContainsKey("AUX"))                {                    step.AUXSets.Clear();                    foreach (var item in RecipeTemplate["AUX"])                    {                        var displayName = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.RecipeEditParameter.AUX.{item.ControlName}.Display");                        var auxUnit = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.RecipeEditParameter.AUX.{item.ControlName}.Unit");                        AddNewAUX(step, item, displayName, auxUnit);                        // step.AUXSets.Add(item.ControlName, new AUXData() { ControlName = item.ControlName, DisplayName = displayName, SetValue = 0, SetUnit = auxUnit, Rampng = 0, RampngUnit = "SLM", AlarmValue = "None", IsCheck = false, MaxValue = 0, MinValue = 0, Unit = auxUnit });                    }                }                StepNo++;            }            return step;        }        private static void AnalysisIsSaved(XmlNode stepNode, Step step)        {            if (stepNode.Attributes["AlarmIsSaved"] != null)            {                bool isSaved = true;                bool.TryParse(stepNode.Attributes["AlarmIsSaved"].Value, out isSaved);                step.AlarmIsSaved = isSaved;            }            else            {                step.AlarmIsSaved = true;            }            if (stepNode.Attributes["MFCIsSaved"] != null)            {                bool isSaved = true;                bool.TryParse(stepNode.Attributes["MFCIsSaved"].Value, out isSaved);                step.MFCIsSaved = isSaved;            }            else            {                step.MFCIsSaved = true;            }            if (stepNode.Attributes["ValveIsSaved"] != null)            {                bool isSaved = true;                bool.TryParse(stepNode.Attributes["ValveIsSaved"].Value, out isSaved);                step.ValveIsSaved = isSaved;            }            else            {                step.ValveIsSaved = true;            }            if (stepNode.Attributes["PressIsSaved"] != null)            {                bool isSaved = true;                bool.TryParse(stepNode.Attributes["PressIsSaved"].Value, out isSaved);                step.PressIsSaved = isSaved;            }            else            {                step.PressIsSaved = true;            }            if (stepNode.Attributes["AUXIsSaved"] != null)            {                bool isSaved = true;                bool.TryParse(stepNode.Attributes["AUXIsSaved"].Value, out isSaved);                step.AUXIsSaved = isSaved;            }            else            {                step.AUXIsSaved = true;            }            if (stepNode.Attributes["TemperatureIsSaved"] != null)            {                bool isSaved = true;                bool.TryParse(stepNode.Attributes["TemperatureIsSaved"].Value, out isSaved);                step.TemperatureIsSaved = isSaved;            }            else            {                step.TemperatureIsSaved = true;            }        }        private static void FromXmlNodeGetTemperatureSets(XmlNode stepNode, Step step, RecipeTemplateColumnBase item)        {            var configHeater = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.Heater.{item.ControlName}.DisplayName");            TempSetData tempSetData = new TempSetData();            tempSetData.Name = item.ControlName;            tempSetData.DisplayName = configHeater != null ? configHeater : item.ControlName;            tempSetData.SetValue = new StringParam() { Name = "SetValue", Value = stepNode.Attributes[$"{item.ControlName}.Set"] != null ? stepNode.Attributes[$"{item.ControlName}.Set"].Value : "0" };            tempSetData.SetUnit = new StringParam() { Name = "SetUnit", Value = stepNode.Attributes[$"{item.ControlName}.SetUnit"] != null ? stepNode.Attributes[$"{item.ControlName}.SetUnit"].Value : "℃" };            tempSetData.RampngValue = new DoubleParam() { Name = "RampngValue", Value = stepNode.Attributes[$"{item.ControlName}.Ramprate"] != null ? stepNode.Attributes[$"{item.ControlName}.Ramprate"].Value : "0" };            tempSetData.RampngUnit = new StringParam() { Name = "RampngUnit", Value = stepNode.Attributes[$"{item.ControlName}.RamprateUnit"] != null ? stepNode.Attributes[$"{item.ControlName}.RamprateUnit"].Value : "℃/min" };            bool tempCheck = false;            if (stepNode.Attributes[$"{item.ControlName}.Check"] != null) bool.TryParse(stepNode.Attributes[$"{item.ControlName}.Check"].Value, out tempCheck);            tempSetData.IsCheck = new BoolParam() { Name = "IsCheck", Value = tempCheck };            double tempHigh = 0;            if (stepNode.Attributes[$"{item.ControlName}.High"] != null) double.TryParse(stepNode.Attributes[$"{item.ControlName}.High"].Value, out tempHigh);            tempSetData.HighValue = new DoubleParam() { Name = "HighValue", Value = tempHigh.ToString() };            double tempLow = 0;            if (stepNode.Attributes[$"{item.ControlName}.Low"] != null) double.TryParse(stepNode.Attributes[$"{item.ControlName}.Low"].Value, out tempLow);            tempSetData.LowValue = new DoubleParam() { Name = "LowValue", Value = tempLow.ToString() };            tempSetData.Unit = stepNode.Attributes[$"{item.ControlName}.Unit"] != null ? stepNode.Attributes[$"{item.ControlName}.Unit"].Value : "0";            if (!step.TemperatureSets.Where(x => x.Name == item.ControlName).Any())            {                step.TemperatureSets.Add(tempSetData);            }            else            {                var tempTemperatureSets = step.TemperatureSets.FirstOrDefault(x => x.Name == item.ControlName);                int getIndex = step.TemperatureSets.IndexOf(tempTemperatureSets);                step.TemperatureSets.Remove(tempTemperatureSets);                step.TemperatureSets.Insert(getIndex, tempSetData);            }        }        private static MFCData StepNodeToMFCData(XmlNode stepNode, RecipeTemplateColumnBase item)        {            MFCData mFCValue = new MFCData();            mFCValue.ControlName = item.ControlName.Replace(".Flow", "");            if (stepNode.Attributes[$"{item.ControlName}.IsSaved"] != null)            {                bool isSaved = true;                bool.TryParse(stepNode.Attributes[$"{item.ControlName}.IsSaved"].Value, out isSaved);                mFCValue.FlagIsSaved = isSaved;            }            else            {                mFCValue.FlagIsSaved = true;            }            var setValue = stepNode.Attributes[$"{item.ControlName}.Set"] != null ? stepNode.Attributes[$"{item.ControlName}.Set"].Value : "0";            mFCValue.SetValue = new StringParam() { Name = "SetValue", Value = setValue };            var strSetUnit = stepNode.Attributes[$"{item.ControlName}.SetUnit"] != null ? stepNode.Attributes[$"{item.ControlName}.SetUnit"].Value : "SLM";            mFCValue.SetUnit = new StringParam() { Name = "SetUnit", Value = strSetUnit };            var rampngValue = stepNode.Attributes[$"{item.ControlName}.Ramprate"] != null ? stepNode.Attributes[$"{item.ControlName}.Ramprate"].Value : "0";            mFCValue.Rampng = new DoubleParam() { Name = "Rampng", Value = rampngValue };            var strRampngUnit = stepNode.Attributes[$"{item.ControlName}.RamprateUnit"] != null ? stepNode.Attributes[$"{item.ControlName}.RamprateUnit"].Value : "SLM";            mFCValue.RampngUnit = new StringParam() { Name = "RampngUnit", Value = strRampngUnit };            var boolIsCheck = stepNode.Attributes[$"{item.ControlName}.Check"] != null ? bool.Parse(stepNode.Attributes[$"{item.ControlName}.Check"].Value) : false;            mFCValue.IsCheck = new BoolParam() { Name = "IsCheck", Value = boolIsCheck };            double maxValue = 0;            if (stepNode.Attributes[$"{item.ControlName}.High"] != null && !string.IsNullOrEmpty(stepNode.Attributes[$"{item.ControlName}.High"].Value))                double.TryParse(stepNode.Attributes[$"{item.ControlName}.High"].Value, out maxValue);            mFCValue.MaxValue = new DoubleParam() { Name = "MaxValue", Value = maxValue.ToString("F3") };            double minValue = 0;            if (stepNode.Attributes[$"{item.ControlName}.Low"] != null && !string.IsNullOrEmpty(stepNode.Attributes[$"{item.ControlName}.Low"].Value))                double.TryParse(stepNode.Attributes[$"{item.ControlName}.High"].Value, out minValue);            mFCValue.MinValue = new DoubleParam() { Name = "MinValue", Value = minValue.ToString("F3") };            mFCValue.Unit = stepNode.Attributes[$"{item.ControlName}.Unit"] != null ? stepNode.Attributes[$"{item.ControlName}.Unit"].Value : "SLM";            mFCValue.ScaleValue = SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.{item.ModuleName}.N2Scale");            return mFCValue;        }        public Step CreateStandbyStep()        {            Step step = new Step();            step.StepNo = 0;            step.Name = "Standby";            step.EndBy = "EndByStepTime";            step.Time = null;            step.SkipWait = "";            step.Command = "NoControl";            //step.ZAxisPosition = "None";            step.AbortRecipeTableIndex = "None";            //step.ZAxisSpeed = "0";            //step.RotatePosition = "None";            //step.RotateDirection = "CW";            //step.RotateSpeed = "0";            //step.RotateInterval = "0";            //step.APC_SetPressure = "0";            step.IsnoneConditionCheck = true;            step.AlarmConditionTable = new StringParam() { Name = "AlarmConditionTable", Value = "1:" };            //step.MfmD1Flow = new MFMValue() { Value = "0", AlarmValue = "None" };            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Valve"))            {                step.ValveSets.Clear();                foreach (var item in RecipeTemplate["Valve"])                {                    if (valveDefaultOpen.Contains(item.ControlName))                    {                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = true });                    }                    else                    {                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = false });                    }                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Temperature"))            {                step.TemperatureSets.Clear();                foreach (var item in RecipeTemplate["Temperature"])                {                    var configHeater = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.Heater.{item.ControlName}.DisplayName");                    var tempSet = new TempSetData(configHeater);                    tempSet.Name = item.ControlName;                    step.TemperatureSets.Add(tempSet);                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFC"))            {                step.MFCSets.Clear();                foreach (var item in RecipeTemplate["MFC"])                {                    step.MFCSets.Add(GetNewMFCData(item.ControlName)); ;                }                if (step.MFCSets != null && step.MFCSets.Count > 0)                {                    for (int i = 0; i < step.MFCSets.Count; i++)                    {                        step.MFCSets[i].No = i + 1;                    }                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFM"))            {                step.MFMSets.Clear();                foreach (var item in RecipeTemplate["MFM"])                {                    step.MFMSets.Add(item.ControlName, new MFMValue() { Value = "0", AlarmValue = "0" }); ;                }            }            step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = "Heater" };            step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = "" };            step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = "" };            step.LoaderCommand = new StringParam() { Name = "LoaderCommand", Value = "None" };            step.PressCommand = new StringParam() { Name = "PressCommand", Value = "None" };            //step.TemperatureProfile = "None";            //step.TemperatureAlarm = "None";            //step.CAPTemperatureAlarm = "None";            //step.TemperatureStabilize = "None";            step.FilmThickFormula = "None";            //隐藏StandBy行            //step.IsVisibility = Visibility.Collapsed;            return step;        }        public Step CreateFirstStep()        {            Step step = new Step();            step.StepNo = 1;            step.Name = "Name";            step.EndBy = "EndByStepTime";            step.Time = null;            step.SkipWait = "";            step.Command = "NoControl";            //step.ZAxisPosition = "None";            step.AbortRecipeTableIndex = "None";            //step.ZAxisSpeed = "0";            //step.RotatePosition = "None";            //step.RotateDirection = "CW";            //step.RotateSpeed = "0";            //step.RotateInterval = "0";            //step.APC_SetPressure = "0";            step.IsnoneConditionCheck = true;            step.AlarmConditionTable = new StringParam() { Name = "AlarmConditionTable", Value = "1:" };            //step.MfmD1Flow = new MFMValue() { Value = "0", AlarmValue = "None" };            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Valve"))            {                step.ValveSets.Clear();                foreach (var item in RecipeTemplate["Valve"])                {                    if (valveDefaultOpen.Contains(item.ControlName))                    {                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = true });                    }                    else                    {                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = false });                    }                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Temperature"))            {                step.TemperatureSets.Clear();                foreach (var item in RecipeTemplate["Temperature"])                {                    var configHeater = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.Heater.{item.ControlName}.DisplayName");                    var tempSet = new TempSetData(configHeater);                    tempSet.Name = item.ControlName;                    step.TemperatureSets.Add(tempSet);                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFC"))            {                step.MFCSets.Clear();                foreach (var item in RecipeTemplate["MFC"])                {                    step.MFCSets.Add(GetNewMFCData(item.ControlName));                }                if (step.MFCSets != null && step.MFCSets.Count > 0)                {                    for (int i = 0; i < step.MFCSets.Count; i++)                    {                        step.MFCSets[i].No = i + 1;                    }                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFM"))            {                step.MFMSets.Clear();                foreach (var item in RecipeTemplate["MFM"])                {                    step.MFMSets.Add(item.ControlName, new MFMValue() { Value = "0", AlarmValue = "0" }); ;                }            }            step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = "Heater" };            step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = "" };            step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = "" };            step.LoaderCommand = new StringParam() { Name = "LoaderCommand", Value = "None" };            step.PressCommand = new StringParam() { Name = "PressCommand", Value = "None" };            //step.TemperatureProfile = "None";            //step.TemperatureAlarm = "None";            //step.CAPTemperatureAlarm = "None";            //step.TemperatureStabilize = "None";            step.FilmThickFormula = "None";            //隐藏StandBy行            //step.IsVisibility = Visibility.Collapsed;            return step;        }        public Step CreateEndStep()        {            Step step = new Step();            step.StepNo = 2;            step.Name = "End";            step.EndBy = "EndByStepTime";            step.Time = null;            step.SkipWait = "";            step.Command = "NoControl";            //step.ZAxisPosition = "None";            step.AbortRecipeTableIndex = "None";            //step.ZAxisSpeed = "0";            //step.RotatePosition = "None";            //step.RotateDirection = "CW";            //step.RotateSpeed = "0";            //step.RotateInterval = "0";            //step.APC_SetPressure = "0";            step.IsnoneConditionCheck = true;            step.AlarmConditionTable = new StringParam() { Name = "AlarmConditionTable", Value = "1:" };            //step.MfmD1Flow = new MFMValue() { Value = "0", AlarmValue = "None" };            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Valve"))            {                step.ValveSets.Clear();                foreach (var item in RecipeTemplate["Valve"])                {                    if (valveDefaultOpen.Contains(item.ControlName))                    {                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = true });                    }                    else                    {                        step.ValveSets.Add(new BoolParam() { Name = item.ControlName, Value = false });                    }                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("Temperature"))            {                step.TemperatureSets.Clear();                foreach (var item in RecipeTemplate["Temperature"])                {                    var configHeater = (string)QueryDataClient.Instance.Service.GetConfig($"PM1.Heater.{item.ControlName}.DisplayName");                    var tempSet = new TempSetData(configHeater);                    tempSet.Name = item.ControlName;                    step.TemperatureSets.Add(tempSet);                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFC"))            {                step.MFCSets.Clear();                foreach (var item in RecipeTemplate["MFC"])                {                    step.MFCSets.Add(GetNewMFCData(item.ControlName)); ;                }                if (step.MFCSets != null && step.MFCSets.Count > 0)                {                    for (int i = 0; i < step.MFCSets.Count; i++)                    {                        step.MFCSets[i].No = i + 1;                    }                }            }            if (RecipeTemplate != null && RecipeTemplate.ContainsKey("MFM"))            {                step.MFMSets.Clear();                foreach (var item in RecipeTemplate["MFM"])                {                    step.MFMSets.Add(item.ControlName, new MFMValue() { Value = "0", AlarmValue = "0" }); ;                }            }            step.TemperatureControlMode = new StringParam() { Name = "TemperatureControlMode", Value = "Heater" };            step.TemperatureCorrect = new StringParam() { Name = "TemperatureCorrect", Value = "" };            step.TemperaturePID = new StringParam() { Name = "TemperaturePID", Value = "" };            step.LoaderCommand = new StringParam() { Name = "LoaderCommand", Value = "None" };            step.PressCommand = new StringParam() { Name = "PressCommand", Value = "None" };            //step.TemperatureProfile = "None";            //step.TemperatureAlarm = "None";            //step.CAPTemperatureAlarm = "None";            //step.TemperatureStabilize = "None";            step.FilmThickFormula = "None";            //隐藏StandBy行            //step.IsVisibility = Visibility.Collapsed;            return step;        }        private static void ReadConditionCheck(XmlNode stepNode, Step step)        {            if (stepNode.Attributes["ConditionCheck"] != null)            {                var conditionCheckValue = stepNode.Attributes["ConditionCheck"].Value;                if (conditionCheckValue != "none")                {                    var subValues = conditionCheckValue.Split(';');                    if (subValues.Count() == 0) return;                    foreach (var item in subValues)                    {                        var itemValues = item.Split(':');                        switch (itemValues[0])                        {                            case "ExternalSensor":                                //step.ExternalSensor = itemValues[1].Split(',').ToArray();                                var externalSensor = itemValues[1].Split(',').ToArray();                                for (int i = 0; i < externalSensor.Count(); i++)                                {                                    step.ExternalSensorName[i] = externalSensor[i].Split('.')[0];                                    step.ExternalSensor[i] = externalSensor[i].Split('.')[1];                                }                                break;                            case "TempStabilize":                                step.TempStabilizeSelected = itemValues[1];                                break;                            case "FinishAutoProfile":                                step.FinishAutoProfile = itemValues[1];                                break;                            //case "TempUpper":                            //    step.TempUpper = int.Parse(itemValues[1]);                            //    break;                            //case "TempLower":                            //    step.TempLower = int.Parse(itemValues[1]);                            //    break;                            case "ReachTemp":                                var reachTemp = itemValues[1];                                if (reachTemp == "None")                                {                                    step.ReachTemp = reachTemp;                                    step.ReachTempValue = 0;                                }                                else                                {                                    step.ReachTemp = itemValues[1].Split(',')[0];                                    step.ReachTempValue = double.Parse(itemValues[1].Split(',')[1]);                                }                                break;                            case "O2Density":                                var o2Density = itemValues[1];                                if (o2Density == "None")                                {                                    step.O2Density = o2Density;                                    step.O2DensityValue = 0;                                }                                else                                {                                    step.O2Density = itemValues[1].Split(',')[0];                                    step.O2DensityValue = int.Parse(itemValues[1].Split(',')[1]);                                }                                break;                            //case "PressureUpper":                            //    step.PressureUpper = double.Parse(itemValues[1]);                            //    break;                            //case "PressureLower":                            //    step.PressureLower = double.Parse(itemValues[1]);                            //    break;                            case "ReachPressure":                                var reachPressure = itemValues[1];                                if (reachPressure == "None")                                {                                    step.ReachPressure = reachPressure;                                    step.ReachPressureVG = reachPressure;                                    step.ReachPressureValue = 0;                                }                                else                                {                                    step.ReachPressure = itemValues[1].Split(',')[0];                                    if (itemValues[1].Split(',').Length > 2)                                    {                                        step.ReachPressureVG = itemValues[1].Split(',')[1];                                        step.ReachPressureValue = double.Parse(itemValues[1].Split(',')[2]);                                    }                                    else                                        step.ReachPressureValue = double.Parse(itemValues[1].Split(',')[1]);                                }                                break;                            case "PressureStabilize":                                if (itemValues[1].Split(',').Length > 1)                                {                                    step.PressureStabilizeSelected = itemValues[1].Split(',')[0];                                    step.PressureStabilizeVG = itemValues[1].Split(',')[1];                                }                                else                                    step.PressureStabilizeSelected = itemValues[1].Split(',')[0];                                break;                            case "ProcessTimeToEnd":                                step.ProcessTimeToEnd = itemValues[1];                                break;                            default:                                break;                        }                    }                }                else                {                    step.IsnoneConditionCheck = true;                }                if (step.ExternalSensor == null || step.ExternalSensor.Count() == 0)                {                    step.ExternalSensor = new string[] { "None", "None", "None", "None", "None", "None", "None" };                }                if (step.TempStabilizeSelected == null)                    step.TempStabilizeSelected = "None";                if (step.FinishAutoProfile == null)                    step.FinishAutoProfile = "None";                if (step.ReachTemp == null)                    step.ReachTemp = "None";                if (step.O2Density == null)                    step.O2Density = "None";                if (step.ReachPressure == null)                    step.ReachPressure = "None";                if (step.PressureStabilizeSelected == null)                    step.PressureStabilizeSelected = "None";                if (step.ProcessTimeToEnd == null)                    step.ProcessTimeToEnd = "None";            }        }        public bool CreateStepTolerance(XmlNode stepNode, out ObservableCollection<Param> step, out ObservableCollection<Param> warning, out ObservableCollection<Param> alarm,            out Dictionary<string, ObservableCollection<Param>> popSettingStep)        {            step = new ObservableCollection<Param>();            warning = new ObservableCollection<Param>();            alarm = new ObservableCollection<Param>();            popSettingStep = new Dictionary<string, ObservableCollection<Param>>();            return true;        }        private bool LoadHeader(XmlNode nodeHeader)        {            if (nodeHeader == null)                return false;            if (nodeHeader.Attributes["CreatedBy"] != null)                this.Creator = nodeHeader.Attributes["CreatedBy"].Value;            if (nodeHeader.Attributes["CreationTime"] != null)                this.CreateTime = DateTime.Parse(nodeHeader.Attributes["CreationTime"].Value);            if (nodeHeader.Attributes["LastRevisedBy"] != null)                this.Revisor = nodeHeader.Attributes["LastRevisedBy"].Value;            if (nodeHeader.Attributes["LastRevisionTime"] != null)                this.ReviseTime = DateTime.Parse(nodeHeader.Attributes["LastRevisionTime"].Value);            if (nodeHeader.Attributes["Description"] != null)                this.Description = nodeHeader.Attributes["Description"].Value;            if (nodeHeader.Attributes["TableIndex"] != null)                this.TableIndex = int.Parse(nodeHeader.Attributes["TableIndex"].Value);            string chamberType = string.Empty;            if (nodeHeader.Attributes["RecipeChamberType"] != null)                this.RecipeChamberType = nodeHeader.Attributes["RecipeChamberType"].Value;            //if (!string.IsNullOrEmpty(chamberType) && chamberType != RecipeChamberType)            //{            //    LOG.Write($"{chamberType} is not accordance with {RecipeChamberType}");            //    return false;            //}            string version = string.Empty;            if (nodeHeader.Attributes["RecipeVersion"] != null)                version = nodeHeader.Attributes["RecipeVersion"].Value;            //if (!string.IsNullOrEmpty(version) && version != RecipeVersion)            //{            //    LOG.Write($"{version} is not accordance with {RecipeVersion}");            //    return false;            //}            return true;        }        private void LoadTables(XmlNode nodeRoot)        {            Tables.Clear();            foreach (XmlNode nodeTable in nodeRoot.ChildNodes)            {                XmlNodeList nodeSteps = nodeTable.SelectNodes($"Step");                RecipeTable recipeDataBase = new RecipeTable();                recipeDataBase.Index = int.Parse(nodeTable.Attributes["Index"].Value);                recipeDataBase.Name = nodeTable.Attributes["Name"].Value;                recipeDataBase.EndStatus = nodeTable.Attributes["EndStatus"].Value;                RecipeDataBase tableData = new RecipeDataBase();                tableData.FastLoadSteps(nodeSteps);                recipeDataBase.TableData = tableData;                Tables.Add(recipeDataBase);            }        }        private void LoadSteps(XmlNodeList steps)        {            Steps.Clear();            PopSettingSteps.Clear();            StepTolerances.Clear();            StepNos.Clear();            int index = 1;            foreach (XmlNode nodeStep in steps)            {                Step step = this.CreateStep(nodeStep);                StepNos.Add(step.StepNo);                Steps.Add(step);                index++;            }            if (StepNos == null || StepNos.Count == 0)            {                StepNo = 1;            }            else            {                StepNo = StepNos.Max() + 1;            }        }        private void FastLoadSteps(XmlNodeList steps)        {            Steps.Clear();            PopSettingSteps.Clear();            StepTolerances.Clear();            StepNos.Clear();            if (steps.Count != 0)            {                Step step = this.CreateStep(steps[0]);                var query1 = (from XmlNode n in steps select n).ToList();                query1.RemoveAt(0);                var allSteps = query1.AsParallel().AsOrdered()                      .Select(x => this.CreateStep(Steps[0], x));                StepNos.Add(step.StepNo);                Steps.Add(step);                foreach (var item in allSteps)                {                    StepNos.Add(item.StepNo);                    Steps.Add(item);                }            }        }        private void LoadConfigs(XmlNode configNode)        {            if (configNode == null)                return;            foreach (Param configItem in ConfigItems)            {                if (configItem is StringParam)                    (configItem as StringParam).Value = configNode.Attributes[configItem.Name]?.Value;                else if (configItem is DoubleParam)                    (configItem as DoubleParam).Value = configNode.Attributes[configItem.Name]?.Value;            }        }        private string GetConditionCheckXmlString(Step parameters)        {            StringBuilder conditionCheckStr = new StringBuilder();            string externalSensor = "";            string[] tempStr = new string[] { "", "", "", "", "", "", "" };            for (int i = 0; i < tempStr.Count(); i++)            {                tempStr[i] = $"{parameters.ExternalSensorName[i]}.{parameters.ExternalSensor[i]}";            }            externalSensor = $"ExternalSensor:{string.Join(",", tempStr.Select(x => x.ToString()))}";            conditionCheckStr.Append($"{externalSensor};");            conditionCheckStr.Append($"TempStabilize:{parameters.TempStabilizeSelected};");            conditionCheckStr.Append($"FinishAutoProfile:{parameters.FinishAutoProfile};");            //conditionCheckStr.Append($"TempUpper:{parameters.TempUpper.ToString()};");            //conditionCheckStr.Append($"TempLower:{parameters.TempLower.ToString()};");            if (parameters.ReachTemp == "None")            {                conditionCheckStr.Append($"ReachTemp:{parameters.ReachTemp};");            }            else            {                conditionCheckStr.Append($"ReachTemp:{parameters.ReachTemp},{parameters.ReachTempValue.ToString()};");            }            if (parameters.O2Density == "None")            {                conditionCheckStr.Append($"O2Density:{parameters.O2Density};");            }            else            {                conditionCheckStr.Append($"O2Density:{parameters.O2Density},{parameters.O2DensityValue.ToString()};");            }            //conditionCheckStr.Append($"PressureUpper:{parameters.PressureUpper.ToString()};");            //conditionCheckStr.Append($"PressureLower:{parameters.PressureLower.ToString()};");            if (parameters.ReachPressure == "None")            {                conditionCheckStr.Append($"ReachPressureWait:{parameters.ReachPressure};");            }            else            {                conditionCheckStr.Append($"ReachPressure:{parameters.ReachPressure},{parameters.ReachPressureVG},{parameters.ReachPressureValue.ToString()};");            }            conditionCheckStr.Append($"PressureStabilize:{parameters.PressureStabilizeSelected},{parameters.PressureStabilizeVG}");            conditionCheckStr.Append($"ProcessTimeToEnd:{parameters.ProcessTimeToEnd}");            return conditionCheckStr.ToString();        }        private void CreateTablesXml(XmlElement nodeData)        {            XmlNode nodeTables = _doc.SelectSingleNode($"Aitex/TableRecipeData/Tables");            if (nodeTables == null)  //创建Recipe文件            {                nodeTables = _doc.CreateElement("Tables");                nodeData.AppendChild(nodeTables);                nodeTables.RemoveAll();                int tableCount = 20;                if (_chamberType.ToLower() == "abort")                {                    tableCount = 10;                }                for (int i = 1; i <= tableCount; i++)                {                    XmlElement nodeTable = _doc.CreateElement("Table");                    nodeTable.SetAttribute("Index", i.ToString());                    nodeTable.SetAttribute("EndStatus", "");                    nodeTable.SetAttribute("Name", "");                    nodeTables.AppendChild(nodeTable);                }            }        }        private void SaveTables(XmlElement nodeData, List<XmlElement> steps, int tableIndex = 1)        {            //XmlNode nodeTables = nodeData.SelectSingleNode($"Aitex/TableRecipeData/Tables");            XmlElement selectednodeTable = (XmlElement)nodeData.ChildNodes[0].SelectSingleNode($"Table[@Index='{tableIndex}']");            var table = this.Tables.FirstOrDefault(x => x.Index == tableIndex);            if (selectednodeTable == null || table == null)                return;            selectednodeTable.SetAttribute("EndStatus", table.EndStatus);            selectednodeTable.SetAttribute("Name", table.Name);            while (selectednodeTable.FirstChild != null)            {                selectednodeTable.RemoveChild(selectednodeTable.FirstChild);            }            steps.ForEach(x => selectednodeTable.AppendChild(x));        }        public string GetXmlString()        {            XmlElement nodeData = _doc.SelectSingleNode($"Aitex/TableRecipeData") as XmlElement;            nodeData.SetAttribute("CreatedBy", Creator);            nodeData.SetAttribute("CreationTime", CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));            nodeData.SetAttribute("LastRevisedBy", Revisor);            nodeData.SetAttribute("LastRevisionTime", ReviseTime.ToString("yyyy-MM-dd HH:mm:ss"));            nodeData.SetAttribute("Description", Description);            nodeData.SetAttribute("RecipeChamberType", RecipeChamberType);            nodeData.SetAttribute("RecipeVersion", RecipeVersion);            nodeData.SetAttribute("RecipePermission", RecipePermission);            nodeData.SetAttribute("RecipeLevel", RecipeLevel);            nodeData.SetAttribute("TableIndex", TableIndex.ToString());            if (!SaveTableRecipeTypes.Contains(RecipeChamberType))            {                XmlNode nodeModule = _doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{_module}']");                if (nodeModule == null)                {                    nodeModule = _doc.CreateElement("Module");                    nodeData.AppendChild(nodeModule);                }                nodeModule.RemoveAll();                (nodeModule as XmlElement).SetAttribute("Name", _module);                int i = 0;                foreach (Step parameters in Steps)                {                    XmlElement nodeWarning = _doc.CreateElement("Warning");                    XmlElement nodeAlarm = _doc.CreateElement("Alarm");                    Dictionary<string, XmlElement> nodePop = new Dictionary<string, XmlElement>();                    foreach (string key in PopEnable.Keys)                    {                        nodePop.Add(key, _doc.CreateElement(key));                    }                    XmlElement nodeStep = _doc.CreateElement("Step");                    if (ToleranceEnable)                    {                        nodeStep.AppendChild(nodeWarning);                        nodeStep.AppendChild(nodeAlarm);                    }                    nodeStep.SetAttribute("StepNo", parameters.StepNo.ToString());                    nodeStep.SetAttribute("Name", parameters.Name);                    nodeStep.SetAttribute("EndBy", parameters.EndBy);                    nodeStep.SetAttribute("Time", parameters.Time);                    nodeStep.SetAttribute("SkipWait", parameters.SkipWait);                    nodeStep.SetAttribute("Command", parameters.Command);                    nodeStep.SetAttribute("AlarmIsSaved", parameters.AlarmIsSaved.ToString());                    nodeStep.SetAttribute("MFCIsSaved", parameters.MFCIsSaved.ToString());                    nodeStep.SetAttribute("ValveIsSaved", parameters.ValveIsSaved.ToString());                    nodeStep.SetAttribute("PressIsSaved", parameters.PressIsSaved.ToString());                    nodeStep.SetAttribute("AUXIsSaved", parameters.AUXIsSaved.ToString());                    nodeStep.SetAttribute("TemperatureIsSaved", parameters.TemperatureIsSaved.ToString());                    if (parameters.IsnoneConditionCheck)                    {                        nodeStep.SetAttribute("ConditionCheck", "none");                    }                    else                    {                        nodeStep.SetAttribute("ConditionCheck", GetConditionCheckXmlString(parameters));                    }                    //nodeStep.SetAttribute("PressureSonserValue", parameters.PressureSonserValue);                    //nodeStep.SetAttribute("PressureSonserValue", parameters.PressureSonserValue);                    //nodeStep.SetAttribute("PressureValveAngle", parameters.PressureValveAngle);                    //nodeStep.SetAttribute("PressureSettingVG", parameters.PressureSettingVG);                    //nodeStep.SetAttribute("SlowVacuumValue", parameters.SlowVacuumValue);                    //nodeStep.SetAttribute("PressureAlarmTableNo", parameters.PressureAlarmTableNo);                    //nodeStep.SetAttribute("ZAxisPosition", parameters.ZAxisPosition);                    //nodeStep.SetAttribute("ZAxisSpeed", parameters.ZAxisSpeed);                    //nodeStep.SetAttribute("RotateDirection", parameters.RotateDirection);                    //nodeStep.SetAttribute("RotatePosition", parameters.RotatePosition);                    //nodeStep.SetAttribute("RotateSpeed", parameters.RotateSpeed);                    //nodeStep.SetAttribute("RotateInterval", parameters.RotateInterval);                    //nodeStep.SetAttribute("APC.SetPressure", parameters.APC_SetPressure);                    //nodeStep.SetAttribute("MfmD1Flow", parameters.MfmD1Flow.ToString());                    //nodeStep.SetAttribute("RFSwitch", parameters.RFSwitch);                    //nodeStep.SetAttribute("RFSetpoint", parameters.RFSetpoint);                    //nodeStep.SetAttribute("RFPowerSetpoint", parameters.RFPowerSetpoint);                    //nodeStep.SetAttribute("CAPSetValue", parameters.CAPSetValue);                    //nodeStep.SetAttribute("CAPRampingValue", parameters.CAPRampingValue);                    //nodeStep.SetAttribute("C1Setpoint", parameters.C1Setpoint);                    //nodeStep.SetAttribute("C2Setpoint", parameters.C2Setpoint);                    //nodeStep.SetAttribute("ForwardPowerAlarmWatchTable", parameters.ForwardPowerAlarmWatchTable);                    //nodeStep.SetAttribute("C1AlarmWatchTable", parameters.C1AlarmWatchTable);                    //nodeStep.SetAttribute("C2AlarmWatchTable", parameters.C2AlarmWatchTable);                    //nodeStep.SetAttribute("PrAlarmWatchTable", parameters.PrAlarmWatchTable);                    //nodeStep.SetAttribute("PIAlarmWatchTable", parameters.PIAlarmWatchTable);                    //nodeStep.SetAttribute("VppAlarmWatchTable", parameters.VppAlarmWatchTable);                    //nodeStep.SetAttribute("VdcAlarmWatchTable", parameters.VdcAlarmWatchTable);                    nodeStep.SetAttribute("AlarmConditionTable", parameters.AlarmConditionTable.Value);                    nodeStep.SetAttribute("AbortRecipeTableIndex", parameters.AbortRecipeTableIndex);                    //nodeStep.SetAttribute("EventSetting", parameters.EventSetting);                    var dpParam = parameters.ValveSets.FirstOrDefault(x => x.Name == "DP");                    foreach (var item in parameters.ValveSets)                    {                        if (item.Name == "MBP")                        {                            if (dpParam != null)                            {                                nodeStep.SetAttribute(item.Name, dpParam.Value ? "Open" : "Close");                            }                            else                            {                                nodeStep.SetAttribute(item.Name, item.Value ? "Open" : "Close");                            }                        }                        else                        {                            nodeStep.SetAttribute(item.Name, item.Value ? "Open" : "Close");                        }                    }                    foreach (var item in parameters.MFCSets)                    {                        nodeStep.SetAttribute($"{item.ControlName}.Flow.IsSaved", item.IsSaved.ToString());                        nodeStep.SetAttribute($"{item.ControlName}.Flow.Set", item.SetValue.Value);                        nodeStep.SetAttribute($"{item.ControlName}.Flow.SetUnit", item.SetUnit.Value);                        nodeStep.SetAttribute($"{item.ControlName}.Flow.Ramprate", item.Rampng.Value);                        nodeStep.SetAttribute($"{item.ControlName}.Flow.RamprateUnit", item.RampngUnit.Value);                        nodeStep.SetAttribute($"{item.ControlName}.Flow.Check", item.IsCheck.Value.ToString());                        nodeStep.SetAttribute($"{item.ControlName}.Flow.High", item.MaxValue.Value.ToString());                        nodeStep.SetAttribute($"{item.ControlName}.Flow.Low", item.MinValue.Value.ToString());                        nodeStep.SetAttribute($"{item.ControlName}.Flow.Unit", item.Unit);                    }                    foreach (var item in parameters.MFMSets)                    {                        nodeStep.SetAttribute(item.Key, parameters.MFMSets[item.Key].ToString());                    }                    foreach (var item in parameters.EXOUSets.Keys)                    {                        nodeStep.SetAttribute(item, parameters.EXOUSets[item].ToString());                    }                    foreach (var item in parameters.TemperatureSets)                    {                        nodeStep.SetAttribute($"{item.Name}.ZoneName", item.Name);                        nodeStep.SetAttribute($"{item.Name}.Set", item.SetValue.Value);                        nodeStep.SetAttribute($"{item.Name}.SetUnit", item.SetUnit.Value);                        nodeStep.SetAttribute($"{item.Name}.Ramprate", item.RampngValue.Value);                        nodeStep.SetAttribute($"{item.Name}.RamprateUnit", item.RampngUnit.Value);                        nodeStep.SetAttribute($"{item.Name}.Check", item.IsCheck.Value.ToString());                        nodeStep.SetAttribute($"{item.Name}.High", item.HighValue.Value.ToString());                        nodeStep.SetAttribute($"{item.Name}.Low", item.LowValue.Value.ToString());                        nodeStep.SetAttribute($"{item.Name}.Unit", item.Unit.ToString());                    }                    nodeStep.SetAttribute("Temperature.ControlMode", parameters.TemperatureControlMode.Value);                    nodeStep.SetAttribute("Temperature.Correct", parameters.TemperatureCorrect.Value);                    nodeStep.SetAttribute("Temperature.PID", parameters.TemperaturePID.Value);                    nodeStep.SetAttribute("Loader.Command", parameters.LoaderCommand.Value);                    nodeStep.SetAttribute("Loader.Speed1", parameters.LoaderSpeed1.Value);                    nodeStep.SetAttribute("Loader.Speed2", parameters.LoaderSpeed2.Value);                    nodeStep.SetAttribute("Loader.Speed3", parameters.LoaderSpeed3.Value);                    nodeStep.SetAttribute("Loader.RPM", parameters.LoaderRPM.Value.ToString());                    nodeStep.SetAttribute("Press.Command", parameters.PressCommand.Value);                    nodeStep.SetAttribute("Press.PID", parameters.PressPID.Value);                    // nodeStep.SetAttribute("Press.Set", parameters.PressSet.Value);                    nodeStep.SetAttribute("Press.Set", GetPressSetValue(parameters));                    // nodeStep.SetAttribute("Press.SlowVacSet", parameters.PressSlowVacSet.Value);                    nodeStep.SetAttribute("Press.SlowVacSet", GetPressSlowVacSet(parameters));                    // nodeStep.SetAttribute("Press.ValveAngleSet", parameters.PressValveAngleSet.Value);                    nodeStep.SetAttribute("Press.ValveAngleSet", RecipeDataBase.GetValveAngleSet(parameters));                    nodeStep.SetAttribute("Press.IsWait", parameters.PressIsWait.Value.ToString());                    nodeStep.SetAttribute("Press.LowWait", parameters.PressLowWait.Value);                    nodeStep.SetAttribute("Press.HighWait", parameters.PressHighWait.Value);                    nodeStep.SetAttribute("Press.WaitUnit", parameters.PressWaitUnit.Value);                    nodeStep.SetAttribute("Press.LowPressWait", parameters.PressLowPressWait.Value);                    // nodeStep.SetAttribute("Press.WaitPress", parameters.WaitPress.Value);                    nodeStep.SetAttribute("Press.WaitPress", RecipeDataBase.GetWaitPress(parameters));                    nodeStep.SetAttribute("FilmThickFormula", parameters.FilmThickFormula);                    foreach (var item in parameters.AUXSets)                    {                        nodeStep.SetAttribute($"AUX.{item.ControlName}.Set", item.SetValue.Value);                        nodeStep.SetAttribute($"AUX.{item.ControlName}.Check", item.IsCheck.Value.ToString());                        nodeStep.SetAttribute($"AUX.{item.ControlName}.High", item.MaxValue.Value);                        nodeStep.SetAttribute($"AUX.{item.ControlName}.Low", item.MinValue.Value);                        nodeStep.SetAttribute($"AUX.{item.ControlName}.CheckUnit", item.SetUnit.Value);                    }                    nodeModule.AppendChild(nodeStep);                    i++;                }                XmlElement nodeConfig = _doc.CreateElement("Config");                foreach (Param parameter in ConfigItems)                {                    if (parameter.Visible == System.Windows.Visibility.Visible)                    {                        if (parameter is IntParam)                            nodeConfig.SetAttribute(parameter.Name, ((IntParam)parameter).Value.ToString());                        else if (parameter is DoubleParam)                        {                            string strValue = ((DoubleParam)parameter).Value;                            bool succed = double.TryParse(strValue, out double dValue);                            if (!succed)                            {                                MessageBox.Show($"The set value of {parameter.DisplayName} is {strValue}, not a valid value");                                return null;                            }                            var config = ConfigItems.Where(m => m.Name == parameter.Name).FirstOrDefault();                            if (config is DoubleParam param1)                            {                                if (param1.Minimun == 0 && param1.Maximun == 0)                                {                                    //没有设定范围                                }                                else if (dValue > param1.Maximun || dValue < param1.Minimun)                                {                                    MessageBox.Show($"The set value of {parameter.DisplayName} is {dValue}, out of the range {param1.Minimun}~{param1.Maximun}");                                    return null;                                }                            }                            nodeConfig.SetAttribute(parameter.Name, ((DoubleParam)parameter).Value.ToString());                        }                        else if (parameter is StringParam)                            nodeConfig.SetAttribute(parameter.Name, ((StringParam)parameter).Value?.ToString());                        else if (parameter is ComboxParam)                            nodeConfig.SetAttribute(parameter.Name, ((ComboxParam)parameter).Value.ToString());                        else if (parameter is LoopComboxParam)                            nodeConfig.SetAttribute(parameter.Name, ((LoopComboxParam)parameter).Value.ToString());                        else if (parameter is PositionParam)                            nodeConfig.SetAttribute(parameter.Name, ((PositionParam)parameter).Value.ToString());                        else if (parameter is BoolParam)                            nodeConfig.SetAttribute(parameter.Name, ((BoolParam)parameter).Value.ToString());                        else if (parameter is StepParam)                            nodeConfig.SetAttribute(parameter.Name, ((StepParam)parameter).Value.ToString());                        else if (parameter is MultipleSelectParam)                        {                            List<string> selected = new List<string>();                            ((MultipleSelectParam)parameter).Options.Apply(                                 opt =>                                 {                                     if (opt.IsChecked)                                         selected.Add(opt.ControlName);                                 }                                                        );                            nodeConfig.SetAttribute(parameter.Name, string.Join(",", selected));                        }                    }                }                nodeModule.AppendChild(nodeConfig);            }            else            {                var CurrentTableSteps = Tables.FirstOrDefault(x => x.Index == TableIndex).TableData.Steps;                CurrentTableSteps.Clear();                Steps.ToList().ForEach(x => CurrentTableSteps.Add(x));                CreateTablesXml(nodeData);                foreach (var item in Tables)                {                    List<XmlElement> StepsXmlElement = new List<XmlElement>();                    foreach (Step parameters in item.TableData.Steps)                    {                        StepsXmlElement.Add(StepToXmlElement(parameters));                    }                    SaveTables(nodeData, StepsXmlElement, item.Index);                }            }            return _doc.OuterXml;        }        public static string GetPressPidValue(Step parameters)        {            string cmd = parameters.PressCommand.Value;            if (cmd == "Slow Vac" || cmd == "Valve Angle" || cmd == "Full Open" || cmd == "Full Close" || cmd == "Hold" ||                cmd == "WaitPressUp1" || cmd == "WaitPressDown1" || cmd == "WaitPressUp2" || cmd == "WaitPressDown2" || cmd == "Zero Set" || cmd == "Cancel Zero")            {                return "";            }            return parameters.PressPID.Value.Replace(",", ":");        }        public static string GetPressSetValue(Step parameters)        {            string rtn = "0";            string cmd = parameters.PressCommand.Value;            if (cmd == "Press" || cmd == "Press2")            {                rtn = parameters.PressSet.Value;            }            return rtn;        }        public static string GetPressSlowVacSet(Step parameters)        {            string rtn = "0";            string cmd = parameters.PressCommand.Value;            if (cmd == "Slow Vac")            {                rtn = parameters.PressSlowVacSet.Value;            }            return rtn;        }        public static string GetValveAngleSet(Step parameters)        {            string rtn = "0";            string cmd = parameters.PressCommand.Value;            if (cmd == "Valve Angle")            {                rtn = parameters.PressValveAngleSet.Value;            }            return rtn;        }        public static string GetWaitPress(Step parameters)        {            string rtn = "0";            string cmd = parameters.PressCommand.Value;            if (cmd == "WaitPressUp1" || cmd == "WaitPressDown1" || cmd == "WaitPressUp2" || cmd == "WaitPressDown2")            {                rtn = parameters.WaitPress.Value;            }            return rtn;        }        private XmlElement StepToXmlElement(Step parameters)        {            XmlElement nodeStep = _doc.CreateElement("Step");            if (ToleranceEnable)            {                //nodeStep.AppendChild(nodeWarning);                //nodeStep.AppendChild(nodeAlarm);            }            nodeStep.SetAttribute("StepNo", parameters.StepNo.ToString());            nodeStep.SetAttribute("Name", parameters.Name);            nodeStep.SetAttribute("EndBy", parameters.EndBy);            nodeStep.SetAttribute("Time", parameters.Time);            nodeStep.SetAttribute("SkipWait", parameters.SkipWait);            nodeStep.SetAttribute("Command", parameters.Command);            nodeStep.SetAttribute("AlarmIsSaved", parameters.AlarmIsSaved.ToString());            nodeStep.SetAttribute("MFCIsSaved", parameters.MFCIsSaved.ToString());            nodeStep.SetAttribute("ValveIsSaved", parameters.ValveIsSaved.ToString());            nodeStep.SetAttribute("PressIsSaved", parameters.PressIsSaved.ToString());            nodeStep.SetAttribute("AUXIsSaved", parameters.AUXIsSaved.ToString());            nodeStep.SetAttribute("TemperatureIsSaved", parameters.TemperatureIsSaved.ToString());            if (parameters.IsnoneConditionCheck)            {                nodeStep.SetAttribute("ConditionCheck", "none");            }            else            {                nodeStep.SetAttribute("ConditionCheck", GetConditionCheckXmlString(parameters));            }            nodeStep.SetAttribute("AlarmConditionTable", parameters.AlarmConditionTable.Value);            nodeStep.SetAttribute("AbortRecipeTableIndex", parameters.AbortRecipeTableIndex);            foreach (var item in parameters.ValveSets)            {                nodeStep.SetAttribute(item.Name, item.Value ? "Open" : "Close");            }            foreach (var item in parameters.MFCSets)            {                nodeStep.SetAttribute($"{item.ControlName}.Flow.IsSaved", item.IsSaved.ToString());                nodeStep.SetAttribute($"{item.ControlName}.Flow.Set", item.SetValue.Value);                nodeStep.SetAttribute($"{item.ControlName}.Flow.SetUnit", item.SetUnit.Value);                nodeStep.SetAttribute($"{item.ControlName}.Flow.Ramprate", item.Rampng.Value);                nodeStep.SetAttribute($"{item.ControlName}.Flow.RamprateUnit", item.RampngUnit.Value);                nodeStep.SetAttribute($"{item.ControlName}.Flow.Check", item.IsCheck.Value.ToString());                nodeStep.SetAttribute($"{item.ControlName}.Flow.High", item.MaxValue.Value.ToString());                nodeStep.SetAttribute($"{item.ControlName}.Flow.Low", item.MinValue.Value.ToString());                nodeStep.SetAttribute($"{item.ControlName}.Flow.Unit", item.Unit);            }            foreach (var item in parameters.MFMSets)            {                nodeStep.SetAttribute(item.Key, parameters.MFMSets[item.Key].ToString());            }            foreach (var item in parameters.EXOUSets.Keys)            {                nodeStep.SetAttribute(item, parameters.EXOUSets[item].ToString());            }            foreach (var item in parameters.TemperatureSets)            {                nodeStep.SetAttribute($"{item.Name}.ZoneName", item.Name);                nodeStep.SetAttribute($"{item.Name}.Set", item.SetValue.Value);                nodeStep.SetAttribute($"{item.Name}.SetUnit", item.SetUnit.Value);                nodeStep.SetAttribute($"{item.Name}.Ramprate", item.RampngValue.Value);                nodeStep.SetAttribute($"{item.Name}.RamprateUnit", item.RampngUnit.Value);                nodeStep.SetAttribute($"{item.Name}.Check", item.IsCheck.Value.ToString());                nodeStep.SetAttribute($"{item.Name}.High", item.HighValue.Value.ToString());                nodeStep.SetAttribute($"{item.Name}.Low", item.LowValue.Value.ToString());                nodeStep.SetAttribute($"{item.Name}.Unit", item.Unit.ToString());            }            nodeStep.SetAttribute("Temperature.ControlMode", parameters.TemperatureControlMode.Value);            nodeStep.SetAttribute("Temperature.Correct", parameters.TemperatureCorrect.Value);            nodeStep.SetAttribute("Temperature.PID", parameters.TemperaturePID.Value);            nodeStep.SetAttribute("Loader.Command", parameters.LoaderCommand.Value);            nodeStep.SetAttribute("Loader.Speed1", parameters.LoaderSpeed1.Value);            nodeStep.SetAttribute("Loader.Speed2", parameters.LoaderSpeed2.Value);            nodeStep.SetAttribute("Loader.Speed3", parameters.LoaderSpeed3.Value);            nodeStep.SetAttribute("Loader.RPM", parameters.LoaderRPM.Value.ToString());            nodeStep.SetAttribute("Press.Command", parameters.PressCommand.Value);            nodeStep.SetAttribute("Press.PID", parameters.PressPID.Value);            nodeStep.SetAttribute("Press.Set", parameters.PressSet.Value);            nodeStep.SetAttribute("Press.SlowVacSet", parameters.PressSlowVacSet.Value);            nodeStep.SetAttribute("Press.ValveAngleSet", parameters.PressValveAngleSet.Value);            nodeStep.SetAttribute("Press.IsWait", parameters.PressIsWait.Value.ToString());            nodeStep.SetAttribute("Press.LowWait", parameters.PressLowWait.Value);            nodeStep.SetAttribute("Press.HighWait", parameters.PressHighWait.Value);            nodeStep.SetAttribute("Press.WaitUnit", parameters.PressWaitUnit.Value);            nodeStep.SetAttribute("Press.LowPressWait", parameters.PressLowPressWait.Value);            nodeStep.SetAttribute("Press.WaitPress", parameters.WaitPress.Value);            nodeStep.SetAttribute("FilmThickFormula", parameters.FilmThickFormula);            // nodeStep.SetAttribute("FilmThickFormula", parameters.FilmThickFormula);            foreach (var item in parameters.AUXSets)            {                nodeStep.SetAttribute($"AUX.{item.ControlName}.Set", item.SetValue.Value);                nodeStep.SetAttribute($"AUX.{item.ControlName}.Check", item.IsCheck.Value.ToString());                nodeStep.SetAttribute($"AUX.{item.ControlName}.High", item.MaxValue.Value);                nodeStep.SetAttribute($"AUX.{item.ControlName}.Low", item.MinValue.Value);                nodeStep.SetAttribute($"AUX.{item.ControlName}.CheckUnit", item.SetUnit.Value);            }            return nodeStep;        }        public RecipeHistory GetRecipeHistory()        {            RecipeHistory recipeHistory = new RecipeHistory();            recipeHistory.CreatedBy = this.Creator;            recipeHistory.CreationTime = this.CreateTime;            recipeHistory.LastRevisedBy = this.Revisor;            recipeHistory.LastRevisionTime = this.ReviseTime;            recipeHistory.Recipe_Description = this.Description;            recipeHistory.Recipe_Type = this.PrefixPath;            recipeHistory.Recipe_Name = this.Name;            recipeHistory.Recipe_Path = $"{this.PrefixPath}\\{this.Name}";            recipeHistory.Recipe_Version = this.RecipeVersion;            recipeHistory.Recipe_Level = this.RecipeLevel;            recipeHistory.Recipe_Premission = this.RecipePermission;            recipeHistory.Recipe_Compare = "";            recipeHistory.Recipe_Content = GetXmlString();            return recipeHistory;        }    }    public class Step : PropertyChangedBase    {        public delegate void TempValueChangedEventHandler(object sender, SetValueEventArgs e);        public event TempValueChangedEventHandler TempValueChangedEvent;        public void OnTempValueChanged(SetValueEventArgs e)        {            if (TempValueChangedEvent != null)            {                TempValueChangedEvent(this, e);            }        }        public delegate void OhterTempValueChangedEventHandler(object sender, SetValueEventArgs e);        public event OhterTempValueChangedEventHandler OhterTempValueChangedEvent;        public void OnOhterTempValueChanged(SetValueEventArgs e)        {            if (OhterTempValueChangedEvent != null)            {                OhterTempValueChangedEvent(this, e);            }        }        public delegate void MFCValueChangedEventHandler(object sender, SetValueEventArgs e);        public event MFCValueChangedEventHandler MFCValueChangedEvent;        public void OnMFCValueChanged(SetValueEventArgs e)        {            if (MFCValueChangedEvent != null)            {                MFCValueChangedEvent(this, e);            }        }        public delegate void ValveValueChangedEventHandler(object sender, SetValueEventArgs e);        public event ValveValueChangedEventHandler ValveValueChangedEvent;        public void OnValveValueChanged(SetValueEventArgs e)        {            if (ValveValueChangedEvent != null)            {                ValveValueChangedEvent(this, e);            }        }        public delegate void AUXValueChangedEventHandler(object sender, SetValueEventArgs e);        public event AUXValueChangedEventHandler AUXValueChangedEvent;        public void OnAUXValueChanged(SetValueEventArgs e)        {            if (AUXValueChangedEvent != null)            {                AUXValueChangedEvent(this, e);            }        }        public Step()        {            SetDelegateEvent();        }        public void SetDelegateEvent()        {            MFCSetsCollectionChanged();            TemperatureSetsCollectionChanged();            ValveSetsCollectionChanged();            AUXSetsCollectionChanged();        }        private void MFCSetsCollectionChanged()        {            foreach (var item in MFCSets)            {                item.PropertyChanged += MFCIsSaved_PropertyChanged;                item.ValueChangedEvent += Item_MFCValueChangedEvent;            }            MFCSets.CollectionChanged += (s, e) =>            {                if (e.OldItems != null)                {                    foreach (MFCData item in e.OldItems)                    {                        item.PropertyChanged -= MFCIsSaved_PropertyChanged;                        item.ValueChangedEvent -= Item_MFCValueChangedEvent;                    }                }                if (e.NewItems != null)                {                    foreach (MFCData item in e.NewItems)                    {                        item.PropertyChanged += MFCIsSaved_PropertyChanged;                        item.ValueChangedEvent += Item_MFCValueChangedEvent;                    }                }            };        }        private void TemperatureSetsCollectionChanged()        {            foreach (var item in TemperatureSets)            {                item.PropertyChanged += TemperatureIsSaved_PropertyChanged;                item.ValueChangedEvent += Item_TempValueChangedEvent;            }            TemperatureSets.CollectionChanged += (s, e) =>            {                if (e.OldItems != null)                {                    foreach (TempSetData item in e.OldItems)                    {                        item.PropertyChanged -= TemperatureIsSaved_PropertyChanged;                        item.ValueChangedEvent -= Item_TempValueChangedEvent;                    }                }                if (e.NewItems != null)                {                    foreach (TempSetData item in e.NewItems)                    {                        item.PropertyChanged += TemperatureIsSaved_PropertyChanged;                        item.ValueChangedEvent += Item_TempValueChangedEvent;                    }                }            };        }        private void ValveSetsCollectionChanged()        {            foreach (var item in ValveSets)            {                item.PropertyChanged += ValveIsSaved_PropertyChanged;                item.ValueChangedEvent += Item_ValveValueChangedEvent;            }            ValveSets.CollectionChanged += (s, e) =>            {                if (e.OldItems != null)                {                    foreach (BoolParam item in e.OldItems)                    {                        item.PropertyChanged -= ValveIsSaved_PropertyChanged;                        item.ValueChangedEvent -= Item_ValveValueChangedEvent;                    }                }                if (e.NewItems != null)                {                    foreach (BoolParam item in e.NewItems)                    {                        item.PropertyChanged += ValveIsSaved_PropertyChanged;                        item.ValueChangedEvent += Item_ValveValueChangedEvent;                    }                }            };        }        private void AUXSetsCollectionChanged()        {            foreach (var item in AUXSets)            {                item.PropertyChanged += AUXIsSaved_PropertyChanged;                item.ValueChangedEvent += Item_AUXValueChangedEvent;            }            AUXSets.CollectionChanged += (s, e) =>            {                if (e.OldItems != null)                {                    foreach (AUXData item in e.OldItems)                    {                        item.PropertyChanged -= AUXIsSaved_PropertyChanged;                        item.ValueChangedEvent -= Item_AUXValueChangedEvent;                    }                }                if (e.NewItems != null)                {                    foreach (AUXData item in e.NewItems)                    {                        item.PropertyChanged += AUXIsSaved_PropertyChanged;                        item.ValueChangedEvent += Item_AUXValueChangedEvent;                    }                }            };        }        public void Item_TempValueChangedEvent(object sender, SetValueEventArgs e)        {            OnTempValueChanged(e);        }        public void Item_MFCValueChangedEvent(object sender, SetValueEventArgs e)        {            OnMFCValueChanged(e);        }        public void Item_ValveValueChangedEvent(object sender, SetValueEventArgs e)        {            OnValveValueChanged(e);        }        public void Item_AUXValueChangedEvent(object sender, SetValueEventArgs e)        {            OnAUXValueChanged(e);        }        public void MFCIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                if (MFCSets.Where(x => x.IsSaved == false).Any())                {                    MFCIsSaved = false;                }                else                {                    if (MFCSetFlagIsSaved)                    {                        MFCIsSaved = true;                    }                    else                    {                        MFCIsSaved = false;                    }                }            }        }        public void TemperatureIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                SetTemperatureIsSaved();            }        }        public void ValveIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                if (ValveSets.Where(x => x.IsSaved == false).Any())                {                    ValveIsSaved = false;                }                else                {                    ValveIsSaved = true;                }            }        }        public void AUXIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                if (AUXSets.Where(x => x.IsSaved == false).Any())                {                    AUXIsSaved = false;                }                else                {                    AUXIsSaved = true;                }            }        }        private void LoaderIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                if (!LoaderCommand.IsSaved || !LoaderSpeed1.IsSaved                  || !LoaderSpeed2.IsSaved || !LoaderSpeed3.IsSaved                  || !LoaderRPM.IsSaved)                {                    LoaderIsSaved = false;                }                else                {                    LoaderIsSaved = true;                }            }        }        private void AlarmIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                if (!AlarmConditionTable.IsSaved)                {                    AlarmIsSaved = false;                }                else                {                    AlarmIsSaved = true;                }            }            else if (e.PropertyName == "Value")            {                if (((Param)sender).IsSaved) return;                SetValueEventArgs setEventArgs = new SetValueEventArgs();                setEventArgs.Sender = this;                setEventArgs.ValueName = "Alarm";                setEventArgs.PropertyName = ((Param)sender).Name;                if (sender is StringParam)                {                    setEventArgs.PropertyValue = ((StringParam)sender).Value;                    OnAlarmValueChanged(setEventArgs);                }            }        }        public delegate void AlarmValueChangedEventHandler(object sender, SetValueEventArgs e);        public event AlarmValueChangedEventHandler AlarmValueChangedEvent;        public void OnAlarmValueChanged(SetValueEventArgs e)        {            if (AlarmValueChangedEvent != null)            {                AlarmValueChangedEvent(this, e);            }        }        private void PressureIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                if (!PressCommand.IsSaved || !PressPID.IsSaved                     || !PressSet.IsSaved || !PressValveAngleSet.IsSaved                      || !PressSlowVacSet.IsSaved || !PressIsWait.IsSaved                       || !PressLowWait.IsSaved || !PressHighWait.IsSaved                        || !PressWaitUnit.IsSaved || !PressLowPressWait.IsSaved                         || !WaitPress.IsSaved)                {                    PressIsSaved = false;                }                else                {                    PressIsSaved = true;                }            }            else if (e.PropertyName == "Value")            {                if (sender is Param)                {                    if (((Param)sender).IsSaved) return;                    SetValueEventArgs setEventArgs = new SetValueEventArgs();                    setEventArgs.Sender = this;                    setEventArgs.ValueName = "Press";                    setEventArgs.PropertyName = ((Param)sender).Name;                    if (sender is DoubleParam)                    {                        setEventArgs.PropertyValue = ((DoubleParam)sender).Value;                        OnPressureValueChanged(setEventArgs);                    }                    else if (sender is StringParam)                    {                        setEventArgs.PropertyValue = ((StringParam)sender).Value;                        OnPressureValueChanged(setEventArgs);                    }                }            }        }        public delegate void PressureValueChangedEventHandler(object sender, SetValueEventArgs e);        public event PressureValueChangedEventHandler PressureValueChangedEvent;        public void OnPressureValueChanged(SetValueEventArgs e)        {            if (PressureValueChangedEvent != null)            {                PressureValueChangedEvent(this, e);            }        }        public delegate void LoaderValueChangedEventHandler(object sender, SetValueEventArgs e);        public event LoaderValueChangedEventHandler LoaderValueChangedEvent;        public void OnLoaderValueChanged(SetValueEventArgs e)        {            if (LoaderValueChangedEvent != null)            {                LoaderValueChangedEvent(this, e);            }        }        private void SetTemperatureIsSaved()        {            if (TemperatureSets.Where(x => x.IsSaved == false).Any() || !TemperatureControlMode.IsSaved || !TemperatureCorrect.IsSaved || !TemperaturePID.IsSaved)            {                TemperatureIsSaved = false;            }            else            {                if (TemperatureSetsFlagIsSaved)                {                    TemperatureIsSaved = true;                }                else                {                    TemperatureIsSaved = false;                }            }        }        public bool UndoMFCChanges()        {            if (MFCIsSaved)            {                if (DialogButton.Yes == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,                      DialogType.CONFIRM,                      $"Recipe MFC is changed Flag, do you want to save it?"))                {                    MFCIsSaved = false;                    MFCSetFlagIsSaved = false;                }            }            else            {                MFCSetFlagIsSaved = true;                foreach (var item in MFCSets)                {                    item.UndoChanges();                }            }            return true;        }        public bool UndoGasChanges()        {            if (ValveIsSaved)            {                if (DialogButton.Yes == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,                      DialogType.CONFIRM,                      $"Recipe Valve is changed Flag, do you want to save it?"))                {                    ValveIsSaved = false;                    ValveFlagIsSaved = false;                }            }            else            {                ValveFlagIsSaved = true;                foreach (var item in ValveSets)                {                    item.UndoChanges();                }            }            return true;        }        public bool UndoAUXChanges()        {            if (AUXIsSaved)            {                if (DialogButton.Yes == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,                      DialogType.CONFIRM,                      $"Recipe AUX is changed Flag, do you want to save it?"))                {                    AUXIsSaved = false;                    AUXFlagIsSaved = false;                }            }            else            {                AUXFlagIsSaved = true;                foreach (var item in AUXSets)                {                    item.UndoChanges();                }            }            return true;        }        public bool UndoTemperatureChanges()        {            if (TemperatureIsSaved)            {                if (DialogButton.Yes == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,                      DialogType.CONFIRM,                      $"Recipe Temperature is changed Flag, do you want to save it?"))                {                    TemperatureIsSaved = false;                    TemperatureSetsFlagIsSaved = false;                }            }            else            {                TemperatureSetsFlagIsSaved = true;                foreach (var item in TemperatureSets)                {                    item.UndoChanges();                }                TemperatureControlMode.UndoChanges();                TemperatureCorrect.UndoChanges();                TemperaturePID.UndoChanges();            }            return true;        }        public bool UndoAlarmChanges()        {            if (AlarmIsSaved)            {                if (DialogButton.Yes == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,                      DialogType.CONFIRM,                      $"Recipe Alarm is changed Flag, do you want to save it?"))                {                    AlarmIsSaved = false;                    AlarmFlagIsSaved = false;                }            }            else            {                AlarmFlagIsSaved = true;                AlarmIsSaved = true;                AlarmConditionTable.UndoChanges();            }            return true;        }        public bool UndoPressChanges()        {            if (PressIsSaved)            {                if (DialogButton.Yes == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,                      DialogType.CONFIRM,                      $"Recipe Press is changed Flag, do you want to save it?"))                {                    PressIsSaved = false;                    PressFlagIsSaved = false;                }            }            else            {                PressFlagIsSaved = true;                PressCommand.UndoChanges();                PressPID.UndoChanges();                PressSet.UndoChanges();                PressSlowVacSet.UndoChanges();                PressValveAngleSet.UndoChanges();                PressLowPressWait.UndoChanges();                WaitPress.UndoChanges();            }            return true;        }        public bool UndoLoaderChanges()        {            if (LoaderIsSaved)            {                if (DialogButton.Yes == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,                         DialogType.CONFIRM,                         $"Recipe Loader is changed Flag, do you want to save it?"))                {                    LoaderIsSaved = false;                }            }            else            {                LoaderIsSaved = true;                LoaderCommand.UndoChanges();                LoaderSpeed1.UndoChanges();                LoaderSpeed2.UndoChanges();                LoaderSpeed3.UndoChanges();                LoaderRPM.UndoChanges();            }            return true;        }        public string Value { get; set; }        private int _stepNo;        public int StepNo        {            get => _stepNo; set            {                _stepNo = value;                NotifyOfPropertyChange("StepNo");            }        }        private string _name;        public string Name        {            get => _name; set            {                _name = value;                NotifyOfPropertyChange("Name");            }        }        public string EndBy { get; set; }        public string Time { get; set; }        public string SkipWait { get; set; }        public string Command { get; set; }        public bool IsChecked { get; set; }        public Visibility IsVisibility { get; set; } = Visibility.Visible;        public bool IsnoneConditionCheck { get; set; }        public string[] ExternalSensorName { get; set; } = new string[] { "SensorTubeATMPressure", "SensorASOpenPosition", "SensorASClosePosition", "SensorEXTIN4", "SensorEXTIN5", "SensorEXTIN6", "SensorEXTIN7" };        public string[] ExternalSensor { get; set; } = new string[] { "None", "None", "None", "None", "None", "None", "None" };        public string TempStabilizeSelected { get; set; }        public string FinishAutoProfile { get; set; }        public string ReachTemp { get; set; }        public double ReachTempValue { get; set; }        public string O2Density { get; set; }        public int O2DensityValue { get; set; }        public string ReachPressure { get; set; }        public string ReachPressureVG { get; set; }        public string PressureStabilizeVG { get; set; }        public double ReachPressureValue { get; set; }        public string PressureStabilizeSelected { get; set; }        public string ProcessTimeToEnd { get; set; }        //public string PressureSonserValue { get; set; }        //public string PressureValveAngle { get; set; }        //public string PressureSettingVG { get; set; }        //public string SlowVacuumValue { get; set; }        //public string PressureAlarmTableNo { get; set; }        //public string ZAxisPosition { get; set; }        //public string ZAxisSpeed { get; set; }        //public string RotatePosition { get; set; }        public string AbortRecipeTableIndex { get; set; }        //public string RFSwitch { get; set; }        //public string RFSetpoint { get; set; }        //public string RFPowerSetpoint { get; set; }        //public string C1Setpoint { get; set; }        //public string C2Setpoint { get; set; }        //public string ForwardPowerAlarmWatchTable { get; set; }        //public string PrAlarmWatchTable { get; set; }        //public string PIAlarmWatchTable { get; set; }        //public string C1AlarmWatchTable { get; set; }        //public string C2AlarmWatchTable { get; set; }        //public string VppAlarmWatchTable { get; set; }        //public string VdcAlarmWatchTable { get; set; }        /// <summary>        /// R 轴方向,CCW(逆时针),CW(顺时针)        /// </summary>      //  public string RotateDirection { get; set; }        //public string RotateSpeed { get; set; }        //public string RotateInterval { get; set; }        //public string APC_SetPressure { get; set; }        private bool _mFCSetFlagIsSaved = true;        public bool MFCSetFlagIsSaved        {            get => _mFCSetFlagIsSaved;            set            {                _mFCSetFlagIsSaved = value;                NotifyOfPropertyChange(nameof(MFCSetFlagIsSaved));            }        }        private bool _mFCIsSaved = true;        public bool MFCIsSaved        {            get => _mFCIsSaved;            set            {                _mFCIsSaved = value;                NotifyOfPropertyChange(nameof(MFCIsSaved));            }        }        private bool _temperatureSetsFlagIsSaved = true;        public bool TemperatureSetsFlagIsSaved        {            get => _temperatureSetsFlagIsSaved;            set            {                _temperatureSetsFlagIsSaved = value;                NotifyOfPropertyChange(nameof(TemperatureSetsFlagIsSaved));            }        }        private bool _temperatureIsSaved = true;        public bool TemperatureIsSaved        {            get => _temperatureIsSaved;            set            {                _temperatureIsSaved = value;                NotifyOfPropertyChange(nameof(TemperatureIsSaved));            }        }        private bool _valveFlagIsSaved = true;        public bool ValveFlagIsSaved        {            get => _valveFlagIsSaved;            set            {                _valveFlagIsSaved = value;                NotifyOfPropertyChange(nameof(ValveFlagIsSaved));            }        }        private bool _valveIsSaved = true;        public bool ValveIsSaved        {            get => _valveIsSaved;            set            {                _valveIsSaved = value;                NotifyOfPropertyChange(nameof(ValveIsSaved));            }        }        private bool _auxFlagIsSaved = true;        public bool AUXFlagIsSaved        {            get => _auxFlagIsSaved;            set            {                _auxFlagIsSaved = value;                NotifyOfPropertyChange(nameof(AUXFlagIsSaved));            }        }        private bool _auxIsSaved = true;        public bool AUXIsSaved        {            get => _auxIsSaved;            set            {                _auxIsSaved = value;                NotifyOfPropertyChange(nameof(AUXIsSaved));            }        }        private bool _loaderIsSaved = true;        public bool LoaderIsSaved        {            get => _loaderIsSaved;            set            {                _loaderIsSaved = value;                NotifyOfPropertyChange(nameof(LoaderIsSaved));            }        }        private bool _pressFlagIsSaved = true;        public bool PressFlagIsSaved        {            get => _pressFlagIsSaved;            set            {                _pressFlagIsSaved = value;                NotifyOfPropertyChange(nameof(PressFlagIsSaved));            }        }        private bool _pressIsSaved = true;        public bool PressIsSaved        {            get => _pressIsSaved;            set            {                _pressIsSaved = value;                NotifyOfPropertyChange(nameof(PressIsSaved));            }        }        private bool _alarmFlagIsSaved = true;        public bool AlarmFlagIsSaved        {            get => _alarmFlagIsSaved;            set            {                _alarmFlagIsSaved = value;                NotifyOfPropertyChange(nameof(AlarmFlagIsSaved));            }        }        private bool _alarmIsSaved = true;        public bool AlarmIsSaved        {            get => _alarmIsSaved;            set            {                _alarmIsSaved = value;                NotifyOfPropertyChange(nameof(AlarmIsSaved));            }        }        public string GasLineN2_Flow { get; set; }        public string GasLineN3_Flow { get; set; }        public MFMValue MfmD1Flow { get; set; }        public ObservableCollection<BoolParam> ValveSets { get; set; } = new ObservableCollection<BoolParam>();        //public Dictionary<string, MFCData> MFCSets { get; set; } = new Dictionary<string, MFCData>();        public ObservableCollection<MFCData> MFCSets { get; set; } = new ObservableCollection<MFCData>();        public Dictionary<string, MFMValue> MFMSets { get; set; } = new Dictionary<string, MFMValue>();        public Dictionary<string, bool> EXOUSets { get; set; } = new Dictionary<string, bool>();        public ObservableCollection<TempSetData> TemperatureSets { get; set; } = new ObservableCollection<TempSetData>();        public Dictionary<string, Dictionary<int, VPData>> VPSets { get; set; } = new Dictionary<string, Dictionary<int, VPData>>();        public ObservableCollection<AUXData> AUXSets { get; set; } = new ObservableCollection<AUXData>();        private void Temperature_PropertyChanged(object sender, PropertyChangedEventArgs e)        {            if (e.PropertyName == nameof(StringParam.IsSaved))            {                SetTemperatureIsSaved();            }            else if (e.PropertyName == "Value")            {                if (sender is Param)                {                    if (((Param)sender).IsSaved) return;                    SetValueEventArgs setValueEventArgs = new SetValueEventArgs();                    setValueEventArgs.Sender = this;                    setValueEventArgs.ValueName = ((Param)sender).Name;                    setValueEventArgs.PropertyName = ((Param)sender).Name;                    if (sender is DoubleParam)                    {                        setValueEventArgs.PropertyValue = ((DoubleParam)sender).Value;                        OnTempValueChanged(setValueEventArgs);                    }                    else if (sender is StringParam)                    {                        var tempObj = sender as StringParam;                        if (tempObj.Name == "TemperatureControlMode" || tempObj.Name == "TemperatureCorrect" || tempObj.Name == "TemperaturePID")                            setValueEventArgs.PropertyValue = ((StringParam)sender).Value;                        if (((StringParam)sender).OldValue != ((StringParam)sender).Value)                        {                            OnTempValueChanged(setValueEventArgs);                        }                    }                }            }        }        private void OtherTemperature_PropertyChanged(object sender, PropertyChangedEventArgs e)        {            if (e.PropertyName == nameof(StringParam.IsSaved))            {                SetTemperatureIsSaved();            }            else if (e.PropertyName == "Value")            {                if (sender is Param)                {                    if (((Param)sender).IsSaved) return;                    SetValueEventArgs setValueEventArgs = new SetValueEventArgs();                    setValueEventArgs.Sender = this;                    setValueEventArgs.ValueName = ((Param)sender).Name;                    setValueEventArgs.PropertyName = ((Param)sender).Name;                    if (sender is DoubleParam)                    {                        setValueEventArgs.PropertyValue = ((DoubleParam)sender).Value;                        OnOhterTempValueChanged(setValueEventArgs);                    }                    else if (sender is StringParam)                    {                        var tempObj = sender as StringParam;                        if (tempObj.Name == "TemperatureControlMode" || tempObj.Name == "TemperatureCorrect" || tempObj.Name == "TemperaturePID")                        {                            setValueEventArgs.PropertyValue = ((StringParam)sender).Value;                            //if (((StringParam)sender).OldValue != ((StringParam)sender).Value)                            //{                                OnOhterTempValueChanged(setValueEventArgs);                            //}                        }                    }                }            }        }        private StringParam _temperatureControlMode;        public StringParam TemperatureControlMode        {            get => _temperatureControlMode;            set            {                _temperatureControlMode = value;                _temperatureControlMode.PropertyChanged += OtherTemperature_PropertyChanged;                NotifyOfPropertyChange(nameof(TemperatureControlMode));            }        }        private StringParam _temperatureCorrect;        public StringParam TemperatureCorrect        {            get => _temperatureCorrect;            set            {                _temperatureCorrect = value;                _temperatureCorrect.PropertyChanged += OtherTemperature_PropertyChanged;                NotifyOfPropertyChange(nameof(TemperatureCorrect));            }        }        private StringParam _temperaturePID;        public StringParam TemperaturePID        {            get => _temperaturePID;            set            {                _temperaturePID = value;                _temperaturePID.PropertyChanged += OtherTemperature_PropertyChanged;                NotifyOfPropertyChange(nameof(TemperaturePID));            }        }        private StringParam _loaderCommand = new StringParam() { Name = "LoaderCommand", Value = "None" };        public StringParam LoaderCommand        {            get => _loaderCommand;            set            {                _loaderCommand = value;                _loaderCommand.PropertyChanged += LoaderIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(LoaderCommand));            }        }        private DoubleParam _loaderSpeed1 = new DoubleParam() { Name = "LoaderSpeed1", Value = "0" };        public DoubleParam LoaderSpeed1        {            get => _loaderSpeed1;            set            {                _loaderSpeed1 = value;                _loaderSpeed1.PropertyChanged += LoaderIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(LoaderSpeed1));            }        }        private DoubleParam _loaderSpeed2 = new DoubleParam() { Name = "LoaderSpeed2", Value = "0" };        public DoubleParam LoaderSpeed2        {            get => _loaderSpeed2;            set            {                _loaderSpeed2 = value;                _loaderSpeed2.PropertyChanged += LoaderIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(LoaderSpeed2));            }        }        private DoubleParam _loaderSpeed3 = new DoubleParam() { Name = "LoaderSpeed3", Value = "0" };        public DoubleParam LoaderSpeed3        {            get => _loaderSpeed3;            set            {                _loaderSpeed3 = value;                _loaderSpeed3.PropertyChanged += LoaderIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(LoaderSpeed3));            }        }        private DoubleParam _loaderRPM = new DoubleParam() { Name = "LoaderRPM", Value = "0" };        public DoubleParam LoaderRPM        {            get => _loaderRPM;            set            {                _loaderRPM = value;                _loaderRPM.PropertyChanged += LoaderIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(LoaderRPM));            }        }        public StringParam _pressCommand = new StringParam() { Name = "PressCommand", Value = "None" };        public StringParam PressCommand        {            get => _pressCommand;            set            {                _pressCommand = value;                _pressCommand.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressCommand));            }        }        private StringParam _pressPID = new StringParam() { Name = "PressPID", Value = "" };        public StringParam PressPID        {            get => _pressPID;            set            {                _pressPID = value;                _pressPID.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(_pressPID));            }        }        private DoubleParam _pressSet = new DoubleParam() { Name = "PressSet", Value = "0" };        public DoubleParam PressSet        {            get => _pressSet;            set            {                _pressSet = value;                _pressSet.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressSet));            }        }        private StringParam _pressValveAngleSet = new StringParam() { Name = "PressValveAngleSet", Value = "0" };        public StringParam PressValveAngleSet        {            get => _pressValveAngleSet;            set            {                _pressValveAngleSet = value;                _pressValveAngleSet.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressValveAngleSet));            }        }        private DoubleParam _pressSlowVacSet = new DoubleParam() { Name = "PressSlowVacSet", Value = "0" };        public DoubleParam PressSlowVacSet        {            get => _pressSlowVacSet;            set            {                _pressSlowVacSet = value;                _pressSlowVacSet.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressSlowVacSet));            }        }        private BoolParam _pressIsWait = new BoolParam() { Name = "PressIsWait", Value = false };        public BoolParam PressIsWait        {            get => _pressIsWait;            set            {                _pressIsWait = value;                _pressIsWait.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressIsWait));            }        }        private StringParam _pressLowWait = new StringParam() { Name = "PressLowWait", Value = "0" };        public StringParam PressLowWait        {            get => _pressLowWait;            set            {                _pressLowWait = value;                _pressLowWait.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressLowWait));            }        }        public StringParam _pressHighWait = new StringParam() { Name = "PressHighWait", Value = "0" };        public StringParam PressHighWait        {            get => _pressHighWait;            set            {                _pressHighWait = value;                _pressHighWait.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressHighWait));            }        }        private StringParam _pressWaitUnit = new StringParam() { Name = "PressWaitUnit", Value = "Torr" };        public StringParam PressWaitUnit        {            get => _pressWaitUnit;            set            {                _pressWaitUnit = value;                _pressWaitUnit.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressWaitUnit));            }        }        private StringParam _pressLowPressWait = new StringParam() { Name = "PressLowPressWait", Value = "None" };        public StringParam PressLowPressWait        {            get => _pressLowPressWait;            set            {                _pressLowPressWait = value;                _pressLowPressWait.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(PressLowPressWait));            }        }        private StringParam _waitPress = new StringParam() { Name = "WaitPress", Value = "0" };        public StringParam WaitPress        {            get => _waitPress;            set            {                _waitPress = value;                _waitPress.PropertyChanged += PressureIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(WaitPress));            }        }        //public string TemperatureProfile { get; set; }        //public string TemperatureAlarm { get; set; }        //public string CAPTemperatureAlarm { get; set; }        //public string CAPSetValue { get; set; }        //public string CAPRampingValue { get; set; }        //public string TemperatureStabilize { get; set; }        //public bool TemperatureReadyCond { get; set; }        private StringParam _alarmConditionTable = new StringParam() { Name = "AlarmConditionTable", Value = "" };        public StringParam AlarmConditionTable        {            get => _alarmConditionTable;            set            {                _alarmConditionTable = value;                _alarmConditionTable.PropertyChanged += AlarmIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(AlarmConditionTable));            }        }        //public string EventSetting { get; set; }        public string FilmThickFormula { get; set; }        public Dictionary<int, AlarmAction> AlarmActionSets { get; set; } = new Dictionary<int, AlarmAction>();        public string DictionaryStepTime(Dictionary<string, string> steptimes)        {            if (steptimes == null) return null;            StringBuilder rtn = new StringBuilder();            foreach (var item in steptimes.Keys)            {                if (steptimes[item] == "00:00:00") continue;                rtn.Append($"{item},{steptimes[item]};");            }            if (rtn.Length > 0) rtn.Remove(rtn.Length - 1, 1);            return rtn.ToString();        }        public Dictionary<string, string> StepTimeToDictionary(string stepTime)        {            Dictionary<string, string> steptimes = new Dictionary<string, string>();            string[] tempTimes = stepTime.Split(';');            foreach (var item in tempTimes)            {                string[] subTimes = item.Split(',');                steptimes.Add(subTimes[0], subTimes[1]);            }            return steptimes;        }    }    public class AlarmAction    {        public string PtocessingType { get; set; }        public string PtocessingDetails { get; set; }    }    public class MFMValue : PropertyChangedBase    {        private string _name;        public string Name        {            get => _name;            set            {                _name = value;                NotifyOfPropertyChange("Name");            }        }        private string _value;        public string Value        {            get => _value;            set            {                _value = value;                NotifyOfPropertyChange("Value");            }        }        private string _alarmValue;        public string AlarmValue        {            get => _alarmValue; set            {                _alarmValue = value;                NotifyOfPropertyChange("AlarmValue");            }        }        public override string ToString()        {            return $"{Value};{AlarmValue}";        }    }    public class MFMData : MFCData    { }    public class MFCData : PropertyChangedBase    {        public delegate void ValueChangedEventHandler(object sender, SetValueEventArgs e);        public event ValueChangedEventHandler ValueChangedEvent;        public MFCData()        {        }        public void OnValueChanged(SetValueEventArgs e)        {            if (ValueChangedEvent != null)            {                ValueChangedEvent(this, e);            }        }        private bool _flagIsSaved = true;        public bool FlagIsSaved        {            get => _flagIsSaved;            set            {                _flagIsSaved = value;                NotifyOfPropertyChange(nameof(FlagIsSaved));                NotifyOfPropertyChange(nameof(IsSaved));            }        }        public bool IsSaved        {            get            {                if (SetValue.IsSaved && SetUnit.IsSaved && Rampng.IsSaved && RampngUnit.IsSaved && IsCheck.IsSaved && MaxValue.IsSaved && MinValue.IsSaved)                {                    if (FlagIsSaved)                    {                        return true;                    }                    else                    {                        return false;                    }                }                else                {                    return false;                }            }        }        public bool UndoChanges()        {            Type type = this.GetType();            PropertyInfo[] properties = type.GetProperties();            foreach (var item in properties)            {                var obj = item.GetValue(this);                if (obj is Param)                {                    ((Param)obj).UndoChanges();                }            }            FlagIsSaved = true;            return true;        }        private void ParamIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == "IsSaved")            {                NotifyOfPropertyChange("IsSaved");            }            else if (e.PropertyName == "Value")            {                if (sender is Param)                {                    if (((Param)sender).IsSaved) return;                    SetValueEventArgs tempSetEventArgs = new SetValueEventArgs();                    tempSetEventArgs.Sender = this;                    tempSetEventArgs.ValueName = this.ControlName;                    tempSetEventArgs.PropertyName = ((Param)sender).Name;                    if (sender is DoubleParam)                    {                        tempSetEventArgs.PropertyValue = ((DoubleParam)sender).Value;                        OnValueChanged(tempSetEventArgs);                    }                    else if (sender is IntParam)                    {                        tempSetEventArgs.PropertyValue = ((IntParam)sender).Value.ToString();                        OnValueChanged(tempSetEventArgs);                    }                    else if (sender is StringParam)                    {                        tempSetEventArgs.PropertyValue = ((StringParam)sender).Value;                        OnValueChanged(tempSetEventArgs);                    }                    else if (sender is BoolParam)                    {                        tempSetEventArgs.PropertyValue = ((BoolParam)sender).Value.ToString();                        OnValueChanged(tempSetEventArgs);                    }                }            }        }        private int _no;        public int No        {            get => _no;            set            {                _no = value;                NotifyOfPropertyChange("No");            }        }        private string _name;        public string Name        {            get => _name;            set            {                _name = value;                NotifyOfPropertyChange("Name");            }        }        public string _unit;        public string Unit        {            get => _unit;            set            {                _unit = value;                NotifyOfPropertyChange("Unit");            }        }        private string _scaleValue;        public string ScaleValue        {            get => _scaleValue;            set            {                _scaleValue = value;                NotifyOfPropertyChange("ScaleValue");            }        }        private string _displayName;        public string DisplayName        {            get => _displayName;            set            {                _displayName = value;                NotifyOfPropertyChange("DisplayName");            }        }        private string _controlName;        public string ControlName        {            get => _controlName;            set            {                _controlName = value;                NotifyOfPropertyChange("ControlName");            }        }        private StringParam _setValue;        public StringParam SetValue        {            get => _setValue;            set            {                _setValue = value;                _setValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(SetValue));            }        }        private StringParam _setUnit = new StringParam() { Name = "SetUnit", Value = "SLM" };        public StringParam SetUnit        {            get => _setUnit;            set            {                _setUnit = value;                _setUnit.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(SetUnit));            }        }        private StringParam _rampngUnit = new StringParam() { Name = "RampngUnit", Value = "SLM" };        public StringParam RampngUnit        {            get => _rampngUnit;            set            {                _rampngUnit = value;                _rampngUnit.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("RampngUnit");            }        }        private DoubleParam _rampng;        public DoubleParam Rampng        {            get => _rampng; set            {                _rampng = value;                NotifyOfPropertyChange("Rampng");                _rampng.PropertyChanged += ParamIsSaved_PropertyChanged;            }        }        private string _alarmValue;        public string AlarmValue        {            get => _alarmValue; set            {                _alarmValue = value;                NotifyOfPropertyChange("AlarmValue");            }        }        private DoubleParam _maxValue = new DoubleParam() { Name = "MaxValue", Value = "0" };        public DoubleParam MaxValue        {            get => _maxValue; set            {                _maxValue = value;                _maxValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("MaxValue");            }        }        private DoubleParam _minValue = new DoubleParam() { Name = "MinValue", Value = "0" };        public DoubleParam MinValue        {            get => _minValue; set            {                _minValue = value;                _minValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("MinValue");            }        }        private BoolParam _isCheck = new BoolParam() { Name = "IsCheck", Value = true };        public BoolParam IsCheck        {            get => _isCheck;            set            {                _isCheck = value;                _isCheck.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("IsCheck");            }        }        private bool _isEnable = true;        public bool IsEnable        {            get => _isEnable;            set            {                _isEnable = value;                NotifyOfPropertyChange("IsEnable");            }        }    }    public class TempSetData : PropertyChangedBase    {        public delegate void ValueChangedEventHandler(object sender, SetValueEventArgs e);        public event ValueChangedEventHandler ValueChangedEvent;        public void OnValueChanged(SetValueEventArgs e)        {            if (ValueChangedEvent != null)            {                ValueChangedEvent(this, e);            }        }        public TempSetData() { }        public bool UndoChanges()        {            Type type = this.GetType();            PropertyInfo[] properties = type.GetProperties();            foreach (var item in properties)            {                var obj = item.GetValue(this);                if (obj is Param)                {                    ((Param)obj).UndoChanges();                }            }            return true;        }        public bool IsSaved        {            get => SetValue.IsSaved && SetUnit.IsSaved && RampngValue.IsSaved && RampngUnit.IsSaved && IsCheck.IsSaved && HighValue.IsSaved && LowValue.IsSaved;        }        public TempSetData(string name)        {            No = 1;            Name = name;            SetValue = new StringParam() { Name = "SetValue", Value = "0" };            SetUnit = new StringParam() { Name = "SetUnit", Value = "℃" };            RampngValue = new DoubleParam() { Name = "RampngValue", Value = "0" };            RampngUnit = new StringParam() { Name = "RampngUnit", Value = "℃/min" };            IsCheck = new BoolParam() { Name = "IsCheck", Value = false };            HighValue = new DoubleParam() { Name = "HighValue", Value = "0" };            LowValue = new DoubleParam() { Name = "LowValue", Value = "0" };            Unit = "℃";        }        private void ParamIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == nameof(Param.IsSaved))            {                NotifyOfPropertyChange(nameof(IsSaved));            }            else if (e.PropertyName == "Value")            {                if (sender is Param)                {                    if (((Param)sender).IsSaved) return;                    SetValueEventArgs tempSetEventArgs = new SetValueEventArgs();                    tempSetEventArgs.Sender = this;                    tempSetEventArgs.ValueName = Name;                    tempSetEventArgs.PropertyName = ((Param)sender).Name;                    if (sender is DoubleParam)                    {                        tempSetEventArgs.PropertyValue = ((DoubleParam)sender).Value;                        OnValueChanged(tempSetEventArgs);                    }                    else if (sender is StringParam)                    {                        tempSetEventArgs.PropertyValue = ((StringParam)sender).Value;                        OnValueChanged(tempSetEventArgs);                    }                }            }        }        public TempSetData(string name, string value) : this(name)        {            var listStr = value.Split(';');            No = 1;            if (listStr.Length > 8)            {                Name = listStr[0];                SetValue.Value = listStr[1];                SetUnit.Value = listStr[2];                RampngValue.Value = listStr[3];                RampngUnit.Value = listStr[4];                bool.TryParse(listStr[5], out bool isCheck);                IsCheck.Value = isCheck;                double.TryParse(listStr[6], out double highValue);                HighValue.Value = highValue.ToString();                double.TryParse(listStr[7], out double lowValue);                LowValue.Value = lowValue.ToString();                Unit = listStr[8];            }        }        private int _no;        public int No        {            get => _no;            set            {                _no = value;                NotifyOfPropertyChange("No");            }        }        private string _name;        public string Name        {            get => _name;            set            {                _name = value;                NotifyOfPropertyChange("Name");            }        }        private string _displayName;        public string DisplayName        {            get => _displayName;            set            {                _displayName = value;                NotifyOfPropertyChange("DisplayName");            }        }        private StringParam _setValue;        public StringParam SetValue        {            get => _setValue;            set            {                _setValue = value;                _setValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("SetValue");            }        }        private StringParam _setUnit;        public StringParam SetUnit        {            get => _setUnit;            set            {                _setUnit = value;                _setUnit.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("SetUnit");            }        }        private DoubleParam _rampngValue;        public DoubleParam RampngValue        {            get => _rampngValue;            set            {                _rampngValue = value;                _rampngValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("RampngValue");            }        }        private StringParam _rampngUnit;        public StringParam RampngUnit        {            get => _rampngUnit;            set            {                _rampngUnit = value;                _rampngUnit.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("RampngUnit");            }        }        private StringParam _alarmValue;        public StringParam AlarmValue        {            get => _alarmValue;            set            {                _alarmValue = value;                NotifyOfPropertyChange("AlarmValue");            }        }        private BoolParam _isCheck;        public BoolParam IsCheck        {            get => _isCheck;            set            {                _isCheck = value;                _isCheck.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("IsCheck");            }        }        private DoubleParam _highValue;        public DoubleParam HighValue        {            get => _highValue;            set            {                _highValue = value;                _highValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("HighValue");            }        }        private DoubleParam _lowValue;        public DoubleParam LowValue        {            get => _lowValue;            set            {                _lowValue = value;                _lowValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("LowValue");            }        }        private string _unit;        public string Unit        {            get => _unit;            set            {                _unit = value;                NotifyOfPropertyChange("Unit");            }        }        public override string ToString()        {            return $"{Name};{SetValue.Value};{SetUnit.Value};{RampngValue.Value};{RampngUnit.Value};{IsCheck.Value};{HighValue.Value};{LowValue.Value};{Unit}";        }    }    public class VPData : PropertyChangedBase    {        private int _no;        public int No        {            get => _no;            set            {                _no = value;                NotifyOfPropertyChange("No");            }        }        private string _name;        public string Name        {            get => _name;            set            {                _name = value;                NotifyOfPropertyChange("Name");            }        }        private bool _isCheck;        public bool IsCheck        {            get => _isCheck;            set            {                _isCheck = value;                NotifyOfPropertyChange("IsCheck");            }        }    }    public class Combination : PropertyChangedBase    {        public ObservableCollection<Param> Params = new ObservableCollection<Param>();        public Combination() { }        public Combination(ObservableCollection<Param> value) : base()        {            if (value != null && value.Count > 0)            {                Params = value;                StringParam subRecipe = value.FirstOrDefault(x => x.Name == "Combination.SubRecipe") as StringParam;                this.SubRecipePath = subRecipe != null ? subRecipe.Value : "";                StringParam alarmRecipe = value.FirstOrDefault(x => x.Name == "Combination.AlarmRecipe") as StringParam;                this.AlarmRecipePath = alarmRecipe != null ? alarmRecipe.Value : "";                StringParam alarmCondition = value.FirstOrDefault(x => x.Name == "Combination.AlarmCondition") as StringParam;                this.AlarmCondition = alarmCondition != null ? alarmCondition.Value : "";                StringParam leakCheck = value.FirstOrDefault(x => x.Name == "Combination.LeakCheck") as StringParam;                this.LeakCheck = leakCheck != null ? leakCheck.Value : "";                StringParam abortRecipe = value.FirstOrDefault(x => x.Name == "Combination.AbortRecipe") as StringParam;                this.AbortRecipePath = abortRecipe != null ? abortRecipe.Value : "";                StringParam pressAPCPID = value.FirstOrDefault(x => x.Name == "Combination.PressAPCPID") as StringParam;                this.PressAPC = pressAPCPID != null ? pressAPCPID.Value : "";                StringParam tempCorrection = value.FirstOrDefault(x => x.Name == "Combination.TempCorrection") as StringParam;                this.TempCorrection = tempCorrection != null ? tempCorrection.Value : "";                StringParam tempPID = value.FirstOrDefault(x => x.Name == "Combination.TempPID") as StringParam;                this.TempPID = tempPID != null ? tempPID.Value : "";                StringParam profileCondition = value.FirstOrDefault(x => x.Name == "Combination.ProfileCondition") as StringParam;                this.ProfileCondition = profileCondition != null ? profileCondition.Value : "";            }        }        public Combination(string value) : base()        {            SetCombinationValue(value);        }        public void SetCombinationValue(string value)        {            if (string.IsNullOrEmpty(value) || !value.Contains(";")) return;            var strList = value.Split(';');            foreach (var item in strList)            {                var subStrList = item.Split(':');                if (string.IsNullOrEmpty(subStrList[0]) || subStrList.Length != 2) continue;                switch (subStrList[0])                {                    case "SubRecipePath":                        SubRecipePath = subStrList[1];                        break;                    case "AlarmRecipePath":                        AlarmRecipePath = subStrList[1];                        break;                    case "AbortRecipePath":                        AbortRecipePath = subStrList[1];                        break;                    case "AlarmCondition":                        AlarmCondition = subStrList[1];                        break;                    case "LeakCheck":                        LeakCheck = subStrList[1];                        break;                    case "PressAPC":                        PressAPC = subStrList[1];                        break;                    case "TempCorrect":                        TempCorrection = subStrList[1];                        break;                    case "TempPID":                        TempPID = subStrList[1];                        break;                    case "ProfileCondition":                        ProfileCondition = subStrList[1];                        break;                    default:                        break;                }            }        }        private string _subRecipePath = "";        public string SubRecipePath        {            get => _subRecipePath;            set            {                _subRecipePath = value;                NotifyOfPropertyChange("SubRecipePath");            }        }        private string _alarmRecipePath = "";        public string AlarmRecipePath        {            get => _alarmRecipePath;            set            {                _alarmRecipePath = value;                NotifyOfPropertyChange("AlarmRecipePath");            }        }        private string _alarmCondition = "";        public string AlarmCondition        {            get => _alarmCondition;            set            {                _alarmCondition = value;                NotifyOfPropertyChange("AlarmCondition");            }        }        private string _leakCheck = "";        public string LeakCheck        {            get => _leakCheck;            set            {                _leakCheck = value;                NotifyOfPropertyChange("LeakCheck");            }        }        private string _AbortRecipePath = "";        public string AbortRecipePath        {            get => _AbortRecipePath;            set            {                _AbortRecipePath = value;                NotifyOfPropertyChange("AbortRecipePath");            }        }        private string _pressAPC = "";        public string PressAPC        {            get => _pressAPC;            set            {                _pressAPC = value;                NotifyOfPropertyChange("PressAPC");            }        }        private string _tempCorrection = "";        public string TempCorrection        {            get => _tempCorrection;            set            {                _tempCorrection = value;                NotifyOfPropertyChange("TempCorrection");            }        }        private string _tempPID = "";        public string TempPID        {            get => _tempPID;            set            {                _tempPID = value;                NotifyOfPropertyChange("TempPID");            }        }        private string _profileCondition = "";        public string ProfileCondition        {            get => _profileCondition;            set            {                _profileCondition = value;                NotifyOfPropertyChange("ProfileCondition");            }        }        public delegate void ChangedValueHandler(string type, string value);        public event ChangedValueHandler ChangedValueEvent;        private void ChangedSelectedFileName(string type, string value)        {            if (ChangedValueEvent != null)            {                ChangedValueEvent(type, value);            }        }        public void SetValueToParam()        {            if (Params.Count > 0)            {                StringParam subRecipe = Params.FirstOrDefault(x => x.Name == "Combination.SubRecipe") as StringParam;                if (subRecipe != null && subRecipe.Value != this.SubRecipePath)                {                    subRecipe.Value = this.SubRecipePath;                    ChangedSelectedFileName("SubRecipe", this.SubRecipePath);                }                StringParam alarmRecipe = Params.FirstOrDefault(x => x.Name == "Combination.AlarmRecipe") as StringParam;                if (alarmRecipe != null && alarmRecipe.Value != this.AlarmRecipePath)                {                    alarmRecipe.Value = this.AlarmRecipePath;                    ChangedSelectedFileName("AlarmRecipe", this.AlarmRecipePath);                }                StringParam alarmCondition = Params.FirstOrDefault(x => x.Name == "Combination.AlarmCondition") as StringParam;                if (alarmCondition != null && alarmCondition.Value != this.AlarmCondition)                {                    alarmCondition.Value = this.AlarmCondition;                    ChangedSelectedFileName("AlarmCondition", this.AlarmCondition);                }                StringParam leakCheck = Params.FirstOrDefault(x => x.Name == "Combination.LeakCheck") as StringParam;                if (leakCheck != null && leakCheck.Value != this.LeakCheck)                {                    leakCheck.Value = this.LeakCheck;                    ChangedSelectedFileName("LeakCheck", this.LeakCheck);                }                StringParam abortRecipe = Params.FirstOrDefault(x => x.Name == "Combination.AbortRecipe") as StringParam;                if (abortRecipe != null && abortRecipe.Value != this.AbortRecipePath)                {                    abortRecipe.Value = this.AbortRecipePath;                    ChangedSelectedFileName("AbortRecipe", this.AbortRecipePath);                }                StringParam pressAPCPID = Params.FirstOrDefault(x => x.Name == "Combination.PressAPCPID") as StringParam;                if (pressAPCPID != null && pressAPCPID.Value != this.PressAPC)                {                    pressAPCPID.Value = this.PressAPC;                    ChangedSelectedFileName("PressAPCPID", this.PressAPC);                }                StringParam tempCorrection = Params.FirstOrDefault(x => x.Name == "Combination.TempCorrection") as StringParam;                if (tempCorrection != null && tempCorrection.Value != this.TempCorrection)                {                    tempCorrection.Value = this.TempCorrection;                    ChangedSelectedFileName("TempCorrection", this.TempCorrection);                }                StringParam tempPID = Params.FirstOrDefault(x => x.Name == "Combination.TempPID") as StringParam;                if (tempPID != null && tempPID.Value != this.TempPID)                {                    tempPID.Value = this.TempPID;                    ChangedSelectedFileName("TempPID", this.TempPID);                }                StringParam profileCondition = Params.FirstOrDefault(x => x.Name == "Combination.ProfileCondition") as StringParam;                if (profileCondition != null && profileCondition.Value != this.ProfileCondition)                {                    profileCondition.Value = this.ProfileCondition;                    ChangedSelectedFileName("ProfileCondition", this.ProfileCondition);                }            }        }        public override string ToString()        {            List<string> strList = new List<string>            {                $"SubRecipePath:{SubRecipePath}",                $"AlarmRecipePath:{AlarmRecipePath}",                $"AlarmCondition:{AlarmCondition}",                $"LeakCheck:{LeakCheck}",                $"AbortRecipePath:{AbortRecipePath}",                $"PressAPC:{PressAPC}",                $"TempCorrect:{TempCorrection}",                $"TempPID:{TempPID}",                $"ProfileCondition:{ProfileCondition}"            };            return string.Join(";", strList);        }    }    public class AUXData : PropertyChangedBase    {        public delegate void ValueChangedEventHandler(object sender, SetValueEventArgs e);        public event ValueChangedEventHandler ValueChangedEvent;        public void OnValueChanged(SetValueEventArgs e)        {            if (ValueChangedEvent != null)            {                ValueChangedEvent(this, e);            }        }        public bool IsSaved        {            get => SetValue.IsSaved && SetUnit.IsSaved && Rampng.IsSaved && RampngUnit.IsSaved && IsCheck.IsSaved && MaxValue.IsSaved && MinValue.IsSaved;        }        public bool UndoChanges()        {            Type type = this.GetType();            PropertyInfo[] properties = type.GetProperties();            foreach (var item in properties)            {                var obj = item.GetValue(this);                if (obj is Param)                {                    ((Param)obj).UndoChanges();                }            }            return true;        }        public bool UndoChanges(AUXData oldAUXData)        {            Type type = this.GetType();            PropertyInfo[] properties = type.GetProperties();            Type oldType = oldAUXData.GetType();            PropertyInfo[] oldProperties = oldType.GetProperties();            foreach (var item in properties)            {                var oldprop = oldProperties.FirstOrDefault(x => x.Name == item.Name);                if (oldprop != null)                {                    var oldObj = oldprop.GetValue(oldAUXData);                    if (oldObj != null)                    {                        var obj = item.GetValue(this);                        if (obj is Param)                        {                            if (oldObj != null && ((Param)oldObj).IsSaved != ((Param)obj).IsSaved)                                ((Param)obj).UndoChanges();                        }                    }                }            }            return true;        }        private void ParamIsSaved_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)        {            if (e.PropertyName == nameof(Param.IsSaved))            {                NotifyOfPropertyChange("IsSaved");            }            else if (e.PropertyName == nameof(DoubleParam.Value))            {                if (sender is Param)                {                    if (((Param)sender).IsSaved) return;                    SetValueEventArgs tempSetEventArgs = new SetValueEventArgs();                    tempSetEventArgs.Sender = this;                    tempSetEventArgs.ValueName = this.ControlName;                    tempSetEventArgs.PropertyName = ((Param)sender).Name;                    if (sender is DoubleParam)                    {                        tempSetEventArgs.PropertyValue = ((DoubleParam)sender).Value;                        OnValueChanged(tempSetEventArgs);                    }                    else if (sender is StringParam)                    {                        tempSetEventArgs.PropertyValue = ((StringParam)sender).Value;                        OnValueChanged(tempSetEventArgs);                    }                    else if (sender is BoolParam)                    {                        tempSetEventArgs.PropertyValue = ((BoolParam)sender).Value.ToString();                        OnValueChanged(tempSetEventArgs);                    }                }            }        }        private int _no;        public int No        {            get => _no;            set            {                _no = value;                NotifyOfPropertyChange("No");            }        }        private string _name;        public string Name        {            get => _name;            set            {                _name = value;                NotifyOfPropertyChange("Name");            }        }        public string _unit;        public string Unit        {            get => _unit;            set            {                _unit = value;                NotifyOfPropertyChange("Unit");            }        }        private string _displayName;        public string DisplayName        {            get => _displayName;            set            {                _displayName = value;                NotifyOfPropertyChange("DisplayName");            }        }        private string _controlName;        public string ControlName        {            get => _controlName;            set            {                _controlName = value;                NotifyOfPropertyChange("ControlName");            }        }        private DoubleParam _setValue;        public DoubleParam SetValue        {            get => _setValue;            set            {                _setValue = value;                _setValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(SetValue));            }        }        private StringParam _setUnit;// = "SLM";        public StringParam SetUnit        {            get => _setUnit;            set            {                _setUnit = value;                _setUnit.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange(nameof(SetUnit));            }        }        private StringParam _rampngUnit = new StringParam() { Name = "RampngUnit", Value = "SLM" };// = "SLM";        public StringParam RampngUnit        {            get => _rampngUnit;            set            {                _rampngUnit = value;                _rampngUnit.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("RampngUnit");            }        }        private DoubleParam _rampng = new DoubleParam() { Name = "Rampng", Value = "0" };        public DoubleParam Rampng        {            get => _rampng; set            {                _rampng = value;                _rampng.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("Rampng");            }        }        private string _alarmValue;        public string AlarmValue        {            get => _alarmValue; set            {                _alarmValue = value;                NotifyOfPropertyChange("AlarmValue");            }        }        private DoubleParam _maxValue;        public DoubleParam MaxValue        {            get => _maxValue; set            {                _maxValue = value;                _maxValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("MaxValue");            }        }        private DoubleParam _minValue;        public DoubleParam MinValue        {            get => _minValue; set            {                _minValue = value;                _minValue.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("MinValue");            }        }        private BoolParam _isCheck;        public BoolParam IsCheck        {            get => _isCheck;            set            {                _isCheck = value;                _isCheck.PropertyChanged += ParamIsSaved_PropertyChanged;                NotifyOfPropertyChange("IsCheck");            }        }        private bool _isEnable = true;        public bool IsEnable        {            get => _isEnable;            set            {                _isEnable = value;                NotifyOfPropertyChange("IsEnable");            }        }    }    public class SetValueEventArgs : EventArgs    {        private Object _sender;        public Object Sender        {            get => _sender;            set            {                _sender = value;            }        }        private string _valueName;        public string ValueName        {            get => _valueName;            set            {                _valueName = value;            }        }        private string _propertyName;        public string PropertyName        {            get => _propertyName;            set            {                _propertyName = value;            }        }        private string _propertyValue;        public string PropertyValue        {            get => _propertyValue;            set            {                _propertyValue = value;            }        }        public SetValueEventArgs()        {        }    }}
 |