using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using System.Xml; using Aitex.Core.RT.Log; using Caliburn.Micro.Core; using MECF.Framework.UI.Client.CenterViews.Configs.Roles; using MECF.Framework.UI.Client.ClientBase; using RecipeEditorLib.DGExtension.CustomColumn; using RecipeEditorLib.RecipeModel.Params; using Sicentury.Core; namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe { public class RecipeData : PropertyChangedBase { public bool IsChanged { get { var changed = !IsSavedDesc; if (!changed) { changed = ChkChanged(Steps) || ChkChanged(PopSettingSteps); } if (!changed) { foreach (var config in ConfigItems) { if (!config.IsSaved) { changed = true; break; } } } return changed; } } private bool _isSavedDesc; public bool IsSavedDesc { get => _isSavedDesc; set { _isSavedDesc = value; NotifyOfPropertyChange("IsSavedDesc"); } } private string name; public string Name { get => name; set { name = value; NotifyOfPropertyChange("Name"); } } private string _chamberType; public string RecipeChamberType { get => _chamberType; set { _chamberType = value; NotifyOfPropertyChange("RecipeChamberType"); } } private string _recipeVersion; public string RecipeVersion { get => _recipeVersion; set { _recipeVersion = value; NotifyOfPropertyChange("RecipeVersion"); } } private string _prefixPath; public string PrefixPath { get => _prefixPath; set { _prefixPath = value; NotifyOfPropertyChange("PrefixPath"); } } private string creator; public string Creator { get => creator; set { creator = value; NotifyOfPropertyChange("Creator"); } } private DateTime createTime; public DateTime CreateTime { get => createTime; set { createTime = value; NotifyOfPropertyChange("CreateTime"); } } private string description; public string Description { get => description; set { description = value; NotifyOfPropertyChange("Description"); } } private string devisor; public string Revisor { get => devisor; set { devisor = value; NotifyOfPropertyChange("Revisor"); } } private DateTime deviseTime; public DateTime ReviseTime { get => deviseTime; set { deviseTime = value; NotifyOfPropertyChange("ReviseTime"); } } private int recipeTotalTime; public int RecipeTotalTime { get => recipeTotalTime; set { recipeTotalTime = value; NotifyOfPropertyChange("RecipeTotalTime"); } } public RecipeStepCollection Steps { get; private set; } public Dictionary PopSettingSteps { get; private set; } public RecipeStepCollection StepTolerances { get; private set; } public RecipeStep ConfigItems { get; private set; } private XmlDocument _doc; public string Module { get; private set; } public bool ToleranceEnable { get; set; } public Dictionary PopEnable { get; set; } public bool IsCompatibleWithCurrentFormat { get; set; } public bool ChkChanged(RecipeStepCollection steps) { foreach (var parameters in steps) { if (parameters.FirstOrDefault(param => param.IsSaved == false) != null) { return true; } } return false; } public bool ChkChanged(Dictionary popSteps) { foreach (var parameters in popSteps.Values) { if (ChkChanged(parameters)) { return true; } } return false; } public RecipeData() { Steps = new RecipeStepCollection(); StepTolerances = new RecipeStepCollection(); PopSettingSteps = new Dictionary(); PopEnable = new Dictionary(); ConfigItems = new RecipeStep(null); IsSavedDesc = true; _doc = new XmlDocument(); var node = _doc.CreateElement("Aitex"); _doc.AppendChild(node); node.AppendChild(_doc.CreateElement("TableRecipeData")); } public void Clear() { Steps.Clear(); PopSettingSteps.Clear(); StepTolerances.Clear(); ConfigItems.Clear(); RecipeChamberType = ""; RecipeVersion = ""; IsSavedDesc = true; Module = ""; } public void DataSaved() { Steps.Save(); StepTolerances.Save(); PopSettingSteps.Values.ToList().ForEach(x => x.Save()); ConfigItems.Save(); IsSavedDesc = true; } public async Task InitData(string prefixPath, string recipeName, string recipeContent, ObservableCollection columnDefine, RecipeStep configDefine, string module, Dispatcher dispatcher = null) { IsCompatibleWithCurrentFormat = false; Name = recipeName; PrefixPath = prefixPath; Module = module; try { _doc = new XmlDocument(); _doc.LoadXml(recipeContent); if (!LoadHeader(_doc.SelectSingleNode("Aitex/TableRecipeData"))) return; var nodeSteps = _doc.SelectNodes($"Aitex/TableRecipeData/Module[@Name='{module}']/Step"); if (nodeSteps == null) nodeSteps = _doc.SelectNodes($"Aitex/TableRecipeData/Step"); var processType = ""; if(PrefixPath.Contains("Process")) { processType = "Process"; } await LoadSteps(columnDefine, nodeSteps, processType, dispatcher); ValidLoopData(); var nodeConfig = _doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{module}']/Config"); if (nodeSteps == null) nodeConfig = _doc.SelectSingleNode($"Aitex/TableRecipeData/Config"); LoadConfigs(configDefine, nodeConfig); IsCompatibleWithCurrentFormat = true; } catch (Exception ex) { LOG.Write(ex); } } public async Task ChangeChamber(ObservableCollection columnDefine, RecipeStep configDefine, string module, Dispatcher dispatcher) { Module = module; try { var nodeSteps = _doc.SelectNodes($"Aitex/TableRecipeData/Module[@Name='{module}']/Step") ?? _doc.SelectNodes($"Aitex/TableRecipeData/Step"); await LoadSteps(columnDefine, nodeSteps, dispatcher: dispatcher); ValidLoopData(); var nodeConfig = _doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{module}']/Config"); if (nodeSteps == null) nodeConfig = _doc.SelectSingleNode($"Aitex/TableRecipeData/Config"); LoadConfigs(configDefine, nodeConfig); } catch (Exception ex) { LOG.Write(ex); } } public void SaveTo(string[] moduleList) { GetXmlString(); var nodeModule = _doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{Module}']"); if (nodeModule == null) { LOG.Write("recipe not find modules," + Name); return; } var 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); var node = nodeModule.Clone() as XmlElement; node.SetAttribute("Name", module); nodeData.AppendChild(node); } } /// /// 创建一个Recipe空步骤。 /// /// Recipe列集合 /// /// 前序Recipe步骤 /// /// 权限 /// /// 创建Step后是否直接隐藏参数值。 /// public RecipeStep CreateStep(ObservableCollection columns, XmlNode stepNode = null, RecipeStep previousRecipeStep = null, MenuPermissionEnum stepPermission = MenuPermissionEnum.MP_READ_WRITE, int? stepId = null) { var recipeStep = new RecipeStep(previousRecipeStep); foreach (var col in columns) { var value = string.Empty; if (!(col is ExpanderColumn) && stepNode != null && !(col is StepColumn) && !(col is PopSettingColumn)) { if (string.IsNullOrEmpty(col.ModuleName) && stepNode.Attributes[col.ControlName] != null) { value = stepNode.Attributes[col.ControlName].Value; } else { if (stepNode.Attributes[col.ControlName] != null && stepNode.SelectSingleNode(col.ModuleName) != null && stepNode.SelectSingleNode(col.ModuleName).Attributes[col.ControlName] != null) value = stepNode.SelectSingleNode(col.ModuleName).Attributes[col.ControlName].Value; } } Param cell = null; switch (col) { case StepColumn _: cell = stepId.HasValue ? new StepParam(stepId.Value) : new StepParam(); cell.Name = col.ControlName; cell.EnableTolerance = col.EnableTolerance; break; case RatioColumn colRatio: if (colRatio.MaxSets == 3) { cell = new Sets3RatioParam(col.Default) { Name = col.ControlName, IsEnabled = col.IsEnable, EnableTolerance = col.EnableTolerance, }; // 如果XML中保存的Value格式正确,则将设置为保存的Value。 if (Sets3RatioParam.ValidateRatioString(value)) { ((Sets3RatioParam)cell).Value = value; } } break; case TextBoxColumn _: cell = new StringParam(string.IsNullOrEmpty(value) ? (string.IsNullOrEmpty(col.Default) ? "" : col.Default) : value) { Name = col.ControlName, IsEnabled = col.IsEnable, EnableTolerance = col.EnableTolerance, }; break; case NumColumn colNum: cell = new IntParam( (int)GlobalDefs.TryParseToDouble(value, GlobalDefs.TryParseToDouble(colNum.Default, colNum.Minimun)), (int)colNum.Minimun, (int)colNum.Maximun) { Name = colNum.ControlName, IsEnabled = colNum.IsEnable, EnableTolerance = colNum.EnableTolerance, }; break; case DoubleColumn colDbl: cell = new DoubleParam( GlobalDefs.TryParseToDouble(value, GlobalDefs.TryParseToDouble(colDbl.Default, colDbl.Minimun)), colDbl.Minimun, colDbl.Maximun) { Name = colDbl.ControlName, IsEnabled = colDbl.IsEnable, Resolution = colDbl.Resolution, EnableTolerance = colDbl.EnableTolerance, }; break; case FlowModeColumn colFlowMode: { //string displayValue; //if (!string.IsNullOrEmpty(value) && // colFlowMode.Options.FirstOrDefault(x => x.ControlName == value) != null) //{ // displayValue = colFlowMode.Options.First(x => x.ControlName == value).DisplayName; //} //else //{ // if (!string.IsNullOrEmpty(colFlowMode.Default) && // colFlowMode.Options.Any(x => x.DisplayName == col.Default)) // { // displayValue = colFlowMode.Default; // } // else // { // var selIndex = 0; // displayValue = displayValue = colFlowMode.Options[selIndex].DisplayName; // } //} cell = new FlowModeParam(string.IsNullOrEmpty(value) ? (string.IsNullOrEmpty(colFlowMode.Default) ? colFlowMode.Options[0].DisplayName : colFlowMode.Default) : value) { Name = colFlowMode.ControlName, Options = colFlowMode.Options, IsEditable = colFlowMode.IsEditable, EnableTolerance = colFlowMode.EnableTolerance, }; break; } case ComboxColumn colCbx: { //string displayValue; //if (!string.IsNullOrEmpty(value) && // colCbx.Options.FirstOrDefault(x => x.ControlName == value) != null) //{ // displayValue = colCbx.Options.First(x => x.ControlName == value).DisplayName; //} //else //{ // if (!string.IsNullOrEmpty(colCbx.Default) && // colCbx.Options.Any(x => x.DisplayName == col.Default)) // { // displayValue = colCbx.Default; // } // else // { // var selIndex = 0; // displayValue = displayValue = colCbx.Options[selIndex].DisplayName; // } //} cell = new ComboxParam(string.IsNullOrEmpty(value) ? (string.IsNullOrEmpty(colCbx.Default) ? colCbx.Options[0].DisplayName : colCbx.Default) : value) { Name = colCbx.ControlName, Options = colCbx.Options, IsEditable = colCbx.IsEditable, EnableTolerance = colCbx.EnableTolerance, }; break; } case LoopComboxColumn colLoopCbx: { var selIndex = 0; cell = new LoopComboxParam(string.IsNullOrEmpty(value) ? colLoopCbx.Options[selIndex].DisplayName : value) { Name = colLoopCbx.ControlName, Options = colLoopCbx.Options, IsEditable = colLoopCbx.IsEditable, IsLoopStep = false, EnableTolerance = colLoopCbx.EnableTolerance, }; break; } case ExpanderColumn _: cell = new ExpanderParam(); break; case PopSettingColumn _: cell = new PopSettingParam() { Name = col.ControlName, DisplayName = col.DisplayName, UnitName = col.UnitName, EnableTolerance = col.EnableTolerance, }; break; } if (cell == null) break; cell.Feedback = col.Feedback; if (col is LoopComboxColumn) { cell.Feedback = LoopCellFeedback; } cell.DisplayName = col.DisplayName; recipeStep.Add(cell); } foreach (var cell in recipeStep) { if (stepPermission == MenuPermissionEnum.MP_NONE) cell.Visible = Visibility.Hidden; else cell.Visible = Visibility.Visible; cell.Feedback?.Invoke(cell); } recipeStep.IsHideValue = Steps.IsHideValue; return recipeStep; } public bool CreateStepTolerance(ObservableCollection columns, Dictionary popSettingColumns, XmlNode stepNode, out RecipeStep step, out RecipeStep warning, out RecipeStep alarm, out Dictionary popSettingStep) { step = new RecipeStep(null); warning = new RecipeStep(null); alarm = new RecipeStep(null); popSettingStep = new Dictionary(); foreach (var col in columns) { var warningValue = string.Empty; var alarmValue = string.Empty; var stepValue = string.Empty; var popValues = new Dictionary>(); if (!(col is ExpanderColumn) && stepNode != null && !(col is StepColumn) && !(col is PopSettingColumn)) { var warningNode = stepNode.SelectSingleNode("Warning"); if (warningNode != null && warningNode.Attributes[col.ControlName] != null) { warningValue = warningNode.Attributes[col.ControlName].Value; } var alarmNode = stepNode.SelectSingleNode("Alarm"); if (alarmNode != null && alarmNode.Attributes[col.ControlName] != null) { alarmValue = alarmNode.Attributes[col.ControlName].Value; } if (string.IsNullOrEmpty(col.ModuleName) && stepNode.Attributes[col.ControlName] != null) { stepValue = stepNode.Attributes[col.ControlName].Value; } else { if (stepNode.Attributes[col.ControlName] != null && stepNode.SelectSingleNode(col.ModuleName) != null && stepNode.SelectSingleNode(col.ModuleName).Attributes[col.ControlName] != null) stepValue = stepNode.SelectSingleNode(col.ModuleName).Attributes[col.ControlName].Value; } } if (col is PopSettingColumn) { foreach (var key in popSettingColumns.Keys) { var popNode = stepNode.SelectSingleNode(key); if (popNode != null) { var Values = new Dictionary(); foreach (var item in popSettingColumns[key]) { if (popNode.Attributes[item.Name] != null) Values.Add(item.Name, popNode.Attributes[item.Name].Value); }; popValues.Add(key, Values); } } } Param stepCell = new DoubleParam(GlobalDefs.TryParseToDouble(stepValue)) { Name = col.ControlName, DisplayName = col.DisplayName, UnitName = col.UnitName, IsEnabled = false, StepCheckVisibility = Visibility.Hidden, }; stepCell.Parent = step; step.Add(stepCell); if (col is PopSettingColumn) { for (var i = 0; i < popSettingColumns[col.ControlName].Count; i++) { var name = popSettingColumns[col.ControlName][i].Name; var value = popValues[col.ControlName].Where(x => x.Key == name).Count() > 0 ? popValues[col.ControlName].First(x => x.Key == name).Value : ""; if (popSettingColumns[col.ControlName][i] is DoubleParam) { stepCell = new DoubleParam(GlobalDefs.TryParseToDouble(value)) { Name = name, DisplayName = popSettingColumns[col.ControlName][i].DisplayName, IsEnabled = false, StepCheckVisibility = Visibility.Hidden, }; } if (popSettingColumns[col.ControlName][i] is StringParam) { stepCell = new StringParam(value) { Name = name, DisplayName = popSettingColumns[col.ControlName][i].DisplayName, IsEnabled = false, StepCheckVisibility = Visibility.Hidden, }; } if (popSettingColumns[col.ControlName][i] is ComboxParam) { stepCell = new ComboxParam(value) { Name = name, DisplayName = popSettingColumns[col.ControlName][i].DisplayName, Options = ((ComboxParam)popSettingColumns[col.ControlName][i]).Options, IsEditable = !col.IsReadOnly, EnableTolerance = col.EnableTolerance, }; } if (!popSettingStep.ContainsKey(col.ControlName)) { popSettingStep.Add(col.ControlName, new RecipeStep(null)); } stepCell.Parent = popSettingStep[col.ControlName]; popSettingStep[col.ControlName].Add(stepCell); } } Param warningCell = new DoubleParam(col.EnableTolerance ? (GlobalDefs.TryParseToDouble(warningValue)) : double.NaN) { Name = col.ControlName, DisplayName = col.DisplayName, UnitName = col.UnitName, IsEnabled = col.EnableTolerance && stepValue != "0", StepCheckVisibility = Visibility.Collapsed, }; warningCell.Feedback = col.Feedback; warningCell.Parent = warning; warning.Add(warningCell); //Param alarmCell = new DoubleParam(col.EnableTolerance ? (string.IsNullOrEmpty(alarmValue) ? "0" : alarmValue) : "*") Param alarmCell = new DoubleParam(col.EnableTolerance ? (GlobalDefs.TryParseToDouble(alarmValue)) : double.NaN) { Name = col.ControlName, DisplayName = col.DisplayName, UnitName = col.UnitName, IsEnabled = col.EnableTolerance && stepValue != "0", StepCheckVisibility = Visibility.Collapsed, }; alarmCell.Feedback = col.Feedback; alarmCell.Parent = alarm; alarm.Add(alarmCell); } return true; } public void ValidLoopData() { if (Steps.Count == 0) return; for (var j = 0; j < Steps[0].Count; j++) { if (Steps[0][j] is LoopComboxParam) { LoopCellFeedback(Steps[0][j]); } } } private void LoopCellFeedback(Param cell) { var loopCell = cell as LoopComboxParam; var rowIndex = -1; var colIndex = -1; for (var i = 0; i < Steps.Count; i++) { for (var j = 0; j < Steps[i].Count; j++) { if (Steps[i][j] == loopCell) { rowIndex = i; colIndex = j; } } } if (rowIndex < 0 || colIndex < 0) return; for (var i = 0; i < Steps.Count; i++) { loopCell = Steps[i][colIndex] as LoopComboxParam; var loopStr = loopCell.Value; var isLoopStart = Regex.IsMatch(loopStr, @"^Loop\x20x\d+$"); var isLoopEnd = Regex.IsMatch(loopStr, @"^Loop End$"); var isNullOrEmpty = string.IsNullOrWhiteSpace(loopStr); if (!isLoopEnd && !isLoopStart && !isNullOrEmpty) { loopCell.IsLoopStep = true; loopCell.IsValidLoop = false; continue; } if (isLoopEnd) { loopCell.IsLoopStep = true; loopCell.IsValidLoop = false; continue; } if (isLoopStart) { if (i + 1 == Steps.Count) { loopCell.IsLoopStep = true; loopCell.IsValidLoop = true; } for (var j = i + 1; j < Steps.Count; j++) { var loopCell2 = Steps[j][colIndex] as LoopComboxParam; var loopStr2 = loopCell2.Value; var isLoopStart2 = Regex.IsMatch(loopStr2, @"^Loop\x20x\d+$"); var isLoopEnd2 = Regex.IsMatch(loopStr2, @"^Loop End$"); var isNullOrEmpty2 = string.IsNullOrWhiteSpace(loopStr2); if (!isLoopEnd2 && !isLoopStart2 && !isNullOrEmpty2) { for (var k = i; k < j + 1; k++) { (Steps[k][colIndex] as LoopComboxParam).IsLoopStep = true; (Steps[k][colIndex] as LoopComboxParam).IsValidLoop = false; } i = j; break; } if (isLoopStart2) { loopCell.IsLoopStep = true; loopCell.IsValidLoop = true; i = j - 1; break; } if (isLoopEnd2) { for (var k = i; k < j + 1; k++) { (Steps[k][colIndex] as LoopComboxParam).IsLoopStep = true; (Steps[k][colIndex] as LoopComboxParam).IsValidLoop = true; } i = j; break; } if (j == Steps.Count - 1) { loopCell.IsLoopStep = true; loopCell.IsValidLoop = true; i = j; break; } } continue; } loopCell.IsLoopStep = false; loopCell.IsValidLoop = false; } } private bool LoadHeader(XmlNode nodeHeader) { if (nodeHeader == null) return false; if (nodeHeader.Attributes["CreatedBy"] != null) Creator = nodeHeader.Attributes["CreatedBy"].Value; if (nodeHeader.Attributes["CreationTime"] != null) CreateTime = DateTime.Parse(nodeHeader.Attributes["CreationTime"].Value); if (nodeHeader.Attributes["LastRevisedBy"] != null) Revisor = nodeHeader.Attributes["LastRevisedBy"].Value; if (nodeHeader.Attributes["LastRevisionTime"] != null) ReviseTime = DateTime.Parse(nodeHeader.Attributes["LastRevisionTime"].Value); if (nodeHeader.Attributes["Description"] != null) Description = nodeHeader.Attributes["Description"].Value; var chamberType = string.Empty; if (nodeHeader.Attributes["RecipeChamberType"] != null) chamberType = nodeHeader.Attributes["RecipeChamberType"].Value; if (!string.IsNullOrEmpty(chamberType) && chamberType != RecipeChamberType) { LOG.Write($"{chamberType} is not accordance with {RecipeChamberType}"); return false; } var 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; } /// /// 加载Recipe。 /// /// /// /// /// /// private async Task LoadSteps(ObservableCollection columns, XmlNodeList steps, string processType = "", Dispatcher dispatcher = null, bool isHideValueWhenLoading = true) { RecipeStep previousStep = null; Steps.Clear(); PopSettingSteps.Clear(); StepTolerances.Clear(); var stepId = 1; RecipeTotalTime = 0; var roleManager = new RoleManager(); var menuPermission = new MenuPermission(); //如果是Process才判断是否要隐藏Step if (processType.Contains("Process")) { roleManager.Initialize(); var roleItem = roleManager.GetRoleByName(BaseApp.Instance.UserContext.RoleName); menuPermission.ParsePermission(roleItem.Role.MenuPermission); } foreach (XmlNode nodeStep in steps) { var stepPermissionEnum = MenuPermissionEnum.MP_READ_WRITE; if (processType.Contains("Process")) { //根据编号获取该Step的用户权限 if (menuPermission.MenuPermissionDictionary.ContainsKey("Step" + stepId)) { if (menuPermission.MenuPermissionDictionary["Step" + stepId] == MenuPermissionEnum.MP_NONE) { //设置rows不可见 stepPermissionEnum = MenuPermissionEnum.MP_NONE; } } } var step = CreateStep(columns, nodeStep, previousStep, stepPermissionEnum, stepId); step.Save(); previousStep = step; RecipeTotalTime += (int)((DoubleParam)step[3]).Value; var t = dispatcher?.BeginInvoke(DispatcherPriority.Background, (Action)(() => { Steps.Add(step); })); if (t != null) await t; else Steps.Add(step); stepId++; } } private void LoadConfigs(RecipeStep configDefine, XmlNode configNode) { ConfigItems.Clear(); foreach (var param in configDefine) { if (param is DoubleParam param1) { var config = new DoubleParam() { Name = param.Name, Value = param1.Value, DisplayName = param.DisplayName, Minimun = param1.Minimun, Maximun = param1.Maximun, Resolution = param1.Resolution }; if (configNode?.Attributes?[param1.Name] != null) config.Value = double.Parse(configNode.Attributes[param1.Name].Value); ConfigItems.Add(config); } if (param is StringParam paramString) { var config = new StringParam() { Name = param.Name, Value = paramString.Value, DisplayName = param.DisplayName, }; if (configNode?.Attributes?[paramString.Name] != null) config.Value = configNode.Attributes[paramString.Name].Value; ConfigItems.Add(config); } } } public RecipeStep CloneStep(ObservableCollection _columns, RecipeStep _sourceParams) { var targetParams = CreateStep(_columns); for (var index = 0; index < _sourceParams.Count; index++) { if (_sourceParams[index] is StringParam) { ((StringParam)targetParams[index]).Value = ((StringParam)_sourceParams[index]).Value; } else if (_sourceParams[index] is Sets3RatioParam) { ((Sets3RatioParam)targetParams[index]).Value = ((Sets3RatioParam)_sourceParams[index]).Value; } else if (_sourceParams[index] is IntParam) { ((IntParam)targetParams[index]).Value = ((IntParam)_sourceParams[index]).Value; } else if (_sourceParams[index] is ComboxParam) { ((ComboxParam)targetParams[index]).Value = ((ComboxParam)_sourceParams[index]).Value; } else if (_sourceParams[index] is LoopComboxParam) { ((LoopComboxParam)targetParams[index]).Value = ((LoopComboxParam)_sourceParams[index]).Value; } else if (_sourceParams[index] is BoolParam) { ((BoolParam)targetParams[index]).Value = ((BoolParam)_sourceParams[index]).Value; } else if (_sourceParams[index] is IntParam) { ((IntParam)targetParams[index]).Value = ((IntParam)_sourceParams[index]).Value; } else if (_sourceParams[index] is DoubleParam) { ((DoubleParam)targetParams[index]).Value = ((DoubleParam)_sourceParams[index]).Value; } } return targetParams; } public string GetXmlString() { try { var 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); var 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); var i = 0; foreach (var parameters in Steps) { var nodeWarning = _doc.CreateElement("Warning"); var nodeAlarm = _doc.CreateElement("Alarm"); var nodePop = new Dictionary(); foreach (var key in PopEnable.Keys) { nodePop.Add(key, _doc.CreateElement(key)); } var nodeStep = _doc.CreateElement("Step"); foreach (var parameter in parameters) { /* if (parameter.Visible != Visibility.Visible) continue;*/ if (ToleranceEnable) { if (parameter.EnableTolerance) { nodeWarning.SetAttribute(parameter.Name, "1"); nodeAlarm.SetAttribute(parameter.Name, "7"); } } if (parameter is IntParam intParam) { //去除Int型数据前面多余的"0" if (int.TryParse(intParam.Value.ToString(), out var result)) { if (result != 0) { intParam.Value = int.Parse(intParam.Value.ToString().TrimStart('0')); } } nodeStep.SetAttribute(intParam.Name, intParam.Value.ToString()); } else if (parameter is DoubleParam doubleParam) { //去除Double型数据前面多余的"0" //if (int.TryParse(((DoubleParam)parameter).Value, out var result)) //{ // if (result != 0) // { // ((DoubleParam)parameter).Value = ((DoubleParam)parameter).Value.TrimStart('0'); // } //} nodeStep.SetAttribute(doubleParam.Name, doubleParam.Value.ToString()); } else if(parameter is Sets3RatioParam param) nodeStep.SetAttribute(param.Name, param.Value); else if (parameter is StringParam stringParam) nodeStep.SetAttribute(stringParam.Name, stringParam.Value.ToString()); else if (parameter is ComboxParam comboxParam) nodeStep.SetAttribute(comboxParam.Name, comboxParam.Options.First(x => x.DisplayName == ((ComboxParam)parameter).Value.ToString()).ControlName); else if (parameter is LoopComboxParam loopComboxParam) nodeStep.SetAttribute(loopComboxParam.Name, loopComboxParam.Value.ToString()); else if (parameter is PositionParam positionParam) nodeStep.SetAttribute(positionParam.Name, positionParam.Value.ToString()); else if (parameter is BoolParam boolParam) nodeStep.SetAttribute(boolParam.Name, boolParam.Value.ToString()); else if (parameter is StepParam stepParam) nodeStep.SetAttribute(stepParam.Name, stepParam.Value.ToString()); else if (parameter is MultipleSelectParam selectParam) { var selected = new List(); selectParam.Options.Apply( opt => { if (opt.IsChecked) selected.Add(opt.ControlName); } ); nodeStep.SetAttribute(selectParam.Name, string.Join(",", selected)); } else if (parameter is PopSettingParam) { SetAttribute(PopSettingSteps[parameter.Name][i], nodePop[parameter.Name]); } } if (ToleranceEnable) { nodeStep.AppendChild(nodeWarning); nodeStep.AppendChild(nodeAlarm); } foreach (var key in PopEnable.Keys) { if (PopEnable[key]) { nodeStep.AppendChild(nodePop[key]); } } nodeModule.AppendChild(nodeStep); i++; } var nodeConfig = _doc.CreateElement("Config"); foreach (var parameter in ConfigItems) { if (parameter.Visible == Visibility.Visible) { if (parameter is IntParam) nodeConfig.SetAttribute(parameter.Name, ((IntParam)parameter).Value.ToString()); else if (parameter is DoubleParam) { /*var strValue = ((DoubleParam)parameter).Value; var succed = double.TryParse(strValue, out var dValue); if (!succed) { MessageBox.Show($"The set value of {parameter.DisplayName} is {strValue}, not a valid value"); return null; }*/ var dValue = ((DoubleParam)parameter).Value; 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) { var selected = new List(); ((MultipleSelectParam)parameter).Options.Apply( opt => { if (opt.IsChecked) selected.Add(opt.ControlName); } ); nodeConfig.SetAttribute(parameter.Name, string.Join(",", selected)); } } } nodeModule.AppendChild(nodeConfig); return _doc.OuterXml; } catch (Exception ex) { LOG.Write(ex.Message); return ""; } } private void SetAttribute(RecipeStep Parameters, XmlElement PopSettingStep) { if (Parameters != null) foreach (var parameter1 in Parameters) { if (parameter1.Visible != Visibility.Visible) continue; if (parameter1 is IntParam) PopSettingStep.SetAttribute(parameter1.Name, ((IntParam)parameter1).Value.ToString()); else if (parameter1 is DoubleParam) PopSettingStep.SetAttribute(parameter1.Name, ((DoubleParam)parameter1).Value.ToString()); else if (parameter1 is StringParam) PopSettingStep.SetAttribute(parameter1.Name, ((StringParam)parameter1).Value.ToString()); else if (parameter1 is ComboxParam) PopSettingStep.SetAttribute(parameter1.Name, ((ComboxParam)parameter1).Value.ToString()); else if (parameter1 is LoopComboxParam) PopSettingStep.SetAttribute(parameter1.Name, ((LoopComboxParam)parameter1).Value.ToString()); else if (parameter1 is PositionParam) PopSettingStep.SetAttribute(parameter1.Name, ((PositionParam)parameter1).Value.ToString()); else if (parameter1 is BoolParam) PopSettingStep.SetAttribute(parameter1.Name, ((BoolParam)parameter1).Value.ToString()); else if (parameter1 is StepParam) PopSettingStep.SetAttribute(parameter1.Name, ((StepParam)parameter1).Value.ToString()); else if (parameter1 is MultipleSelectParam) { var selected1 = new List(); ((MultipleSelectParam)parameter1).Options.Apply( opt => { if (opt.IsChecked) selected1.Add(opt.ControlName); } ); PopSettingStep.SetAttribute(parameter1.Name, string.Join(",", selected1)); } } } public string ToXmlString() { var builder = new StringBuilder(); builder.Append(""); builder.Append(string.Format("", Creator, CreateTime.ToString("yyyy-MM-dd HH:mm:ss"), Revisor, ReviseTime.ToString("yyyy-MM-dd HH:mm:ss"), Description, RecipeChamberType, RecipeVersion)); foreach (var parameters in Steps) { builder.Append("(); ((MultipleSelectParam)parameter).Options.Apply( opt => { if (opt.IsChecked) selected.Add(opt.ControlName); } ); builder.Append(parameter.Name + "=\"" + string.Join(",", selected) + "\" "); } } } builder.Append("/>"); } builder.Append("(); ((MultipleSelectParam)parameter).Options.Apply( opt => { if (opt.IsChecked) selected.Add(opt.ControlName); } ); builder.Append(parameter.Name + "=\"" + string.Join(",", selected) + "\" "); } } } builder.Append("/>"); builder.Append(""); return builder.ToString(); } } }