瀏覽代碼

add all recipe save as

chenzk 2 周之前
父節點
當前提交
23c137c6af

+ 117 - 2
CyberX8_MainPages/ViewModels/DepRecipeViewModel.cs

@@ -4,11 +4,12 @@ using Aitex.Core.UI.Dialog;
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
 using Caliburn.Micro.Core;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_Core;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -272,6 +273,7 @@ namespace CyberX8_MainPages.ViewModels
             CreateCommand = new DelegateCommand<object>(CreateAction);
             EditCommand = new DelegateCommand<object>(EditAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             AddBelowCommand = new DelegateCommand<object>(AddBelowAction);
             AddAboveCommand = new DelegateCommand<object>(AddAboveAction);
             MoveUpCommand=new DelegateCommand<object>(MoveUpAction);
@@ -457,6 +459,119 @@ namespace CyberX8_MainPages.ViewModels
             }
         }
         /// <summary>
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            DepRecipe recipe = new DepRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new DepRecipe();
+
+                        //复制属性
+                        //recipe.Chemistry = Recipe.Chemistry;
+                        //recipe.AnodeType = Recipe.AnodeType;
+                        //recipe.CurrentWarningLevel = Recipe.CurrentWarningLevel;
+                        //recipe.CycleClampsMaxTries = Recipe.CycleClampsMaxTries;
+                        //recipe.FaultPercent = Recipe.FaultPercent;
+                        //recipe.PlatingDelaySeconds = Recipe.PlatingDelaySeconds;
+                        //recipe.VolatageLimitMax = Recipe.VolatageLimitMax;
+                        //recipe.VolatageLimitMin = Recipe.VolatageLimitMin;
+                        //recipe.VoltageWarningLevel = Recipe.VoltageWarningLevel;
+                        //recipe.CycleClampsEnable = Recipe.CycleClampsEnable;
+                        //recipe.HotPlatingCurrentOn = Recipe.HotPlatingCurrentOn;
+                        //recipe.MultiAnodeType = Recipe.MultiAnodeType;
+                        //recipe.DepositionPlatingSteps = Recipe.DepositionPlatingSteps;
+                        //recipe.DepositionTotalTime = Recipe.DepositionTotalTime;
+                        //recipe.DepositionTotalCurrent = Recipe.DepositionTotalCurrent;
+                        //recipe.TotalTime = Recipe.TotalTime;
+
+                        //recipe.CurrentRampProfileSteps = new ObservableCollection<CurrentRampProfile>();
+                        //foreach(var item in Recipe.CurrentRampProfileSteps)
+                        //{
+                        //    CurrentRampProfile currentRampProfile = new CurrentRampProfile();
+
+                        //    currentRampProfile.CurrentRampDurartionSeconds = item.CurrentRampDurartionSeconds;
+                        //    currentRampProfile.ForwardAmps = item.ForwardAmps;
+                        //    currentRampProfile.ForwardAmps2 = item.ForwardAmps2;
+                        //    currentRampProfile.ForwardAmps3 = item.ForwardAmps3;
+                        //    currentRampProfile.ForwardAmps4 = item.ForwardAmps4;
+                        //    currentRampProfile.ForwardAmps5 = item.ForwardAmps5;
+                        //    currentRampProfile.ForwardAmps6 = item.ForwardAmps6;
+                        //    currentRampProfile.PulseEnabled = item.PulseEnabled;
+                        //    currentRampProfile.ReversedAmps = item.ReversedAmps;
+                        //    currentRampProfile.ShearPlateSpeed = item.ShearPlateSpeed;
+
+                        //    recipe.CurrentRampProfileSteps.Add(currentRampProfile);
+                        //}
+
+                        //recipe.PulsePowerSupplySteps = new ObservableCollection<PulsePowerSupplyStep>();
+                        //foreach (var item in Recipe.PulsePowerSupplySteps)
+                        //{
+                        //    PulsePowerSupplyStep pulsePowerSupplyStep = new PulsePowerSupplyStep();
+
+                        //    pulsePowerSupplyStep.DurationHundredsMicroSeconds = item.DurationHundredsMicroSeconds;
+                        //    pulsePowerSupplyStep.Type = item.Type;
+                        //    recipe.PulsePowerSupplySteps.Add(pulsePowerSupplyStep);
+                        //}
+                        recipe = (DepRecipe)PropertyUtil.Clone(Recipe);
+
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<DepRecipe>(ENGINEERING, recipe.Ppid, "dep", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
+        /// <summary>
+        /// 检验名称是否已经存在
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        private bool CheckNameExist(string name)
+        {
+            foreach (string item in _recipeNodeDic.Keys)
+            {
+                if (item == name)
+                {
+                    MessageBox.Show($"{name} is exsit", "Save Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                    return true;
+                }
+            }
+            return false;
+        }
+        /// <summary>
         /// 检验合法性
         /// </summary>
         /// <param name="editType"></param>

+ 57 - 2
CyberX8_MainPages/ViewModels/HvdRecipeViewModel.cs

@@ -4,11 +4,12 @@ using Aitex.Core.UI.Dialog;
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
 using Caliburn.Micro.Core;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_Core;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -156,6 +157,7 @@ namespace CyberX8_MainPages.ViewModels
             CreateCommand = new DelegateCommand<object>(CreateAction);
             EditCommand = new DelegateCommand<object>(EditAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             InitializeProprtyValidResultDictionary();
         }
         /// <summary>
@@ -294,6 +296,59 @@ namespace CyberX8_MainPages.ViewModels
             }
         }
         /// <summary>
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            HvdRecipe recipe = new HvdRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new HvdRecipe();
+                        recipe = (HvdRecipe)PropertyUtil.Clone(Recipe);
+                        //recipe.DryTime = Recipe.DryTime; 
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+
+
+                        Enable = true;
+                        _isEdit = false;
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<HvdRecipe>(ENGINEERING, recipe.Ppid, "hvd", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
+        /// <summary>
         /// 检验合法性
         /// </summary>
         /// <param name="editType"></param>

+ 71 - 2
CyberX8_MainPages/ViewModels/PwtRecipeViewModel.cs

@@ -4,11 +4,12 @@ using Aitex.Core.UI.Dialog;
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
 using Caliburn.Micro.Core;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_Core;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -158,6 +159,7 @@ namespace CyberX8_MainPages.ViewModels
             CreateCommand = new DelegateCommand<object>(CreateAction);
             EditCommand = new DelegateCommand<object>(EditAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             InitializeProprtyValidResultDictionary();
         }
         /// <summary>
@@ -292,6 +294,73 @@ namespace CyberX8_MainPages.ViewModels
                 }
             }
         }
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            PwtRecipe recipe = new PwtRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new PwtRecipe();
+
+                        //recipe.NumberOfScans = Recipe.NumberOfScans;
+                        //recipe.PrewetModuleType = Recipe.PrewetModuleType;
+                        //recipe.VacuumHoldTime = Recipe.VacuumHoldTime;
+                        //recipe.VacuumLowLimit = Recipe.VacuumLowLimit;
+                        //recipe.WaterHoldTime = Recipe.WaterHoldTime;
+                        //recipe.KeepWet = Recipe.KeepWet;
+                        recipe = (PwtRecipe)PropertyUtil.Clone(Recipe);
+
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<PwtRecipe>(ENGINEERING, recipe.Ppid, "pwt", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
+        private bool CheckNameExist(string name)
+        {
+            foreach (string item in _recipeNodeDic.Keys)
+            {
+                if (item == name)
+                {
+                    MessageBox.Show($"{name} is exsit", "Save Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                    return true;
+                }
+            }
+            return false;
+        }
         /// <summary>
         /// 检验合法性
         /// </summary>

+ 70 - 2
CyberX8_MainPages/ViewModels/QdrRecipeViewModel.cs

@@ -4,11 +4,12 @@ using Aitex.Core.UI.Dialog;
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
 using Caliburn.Micro.Core;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_Core;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -156,6 +157,7 @@ namespace CyberX8_MainPages.ViewModels
             CreateCommand = new DelegateCommand<object>(CreateAction);
             EditCommand = new DelegateCommand<object>(EditAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             InitializeProprtyValidResultDictionary();
         }
         /// <summary>
@@ -308,6 +310,72 @@ namespace CyberX8_MainPages.ViewModels
             }
         }
         /// <summary>
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            QdrRecipe recipe = new QdrRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new QdrRecipe();
+
+                        recipe = (QdrRecipe)PropertyUtil.Clone(Recipe);
+                        //recipe.Step1DwellTimeSeconds = Recipe.Step1DwellTimeSeconds;
+                        //recipe.Step1NumberOfRinse = Recipe.Step1NumberOfRinse;
+                        //recipe.Step1N2BubbleOn = Recipe.Step1N2BubbleOn;
+                        //recipe.Step1NumberOfDumpToMetalDrain = Recipe.Step1NumberOfDumpToMetalDrain;
+                        //recipe.Step2DwellTimeSeconds = Recipe.Step2DwellTimeSeconds;
+                        //recipe.Step2N2BubbleOn = Recipe.Step2N2BubbleOn;
+                        //recipe.Step2NumberOfRinse = Recipe.Step2NumberOfRinse;
+                        //recipe.FinalRinseDry = Recipe.FinalRinseDry;
+                        //recipe.FinalRinsePulseClampTime = Recipe.FinalRinsePulseClampTime;
+                        //recipe.FinalRinseSlowDrainTime = Recipe.FinalRinseSlowDrainTime;
+                        //recipe.ResistivityDurationSeconds = Recipe.ResistivityDurationSeconds;
+                        //recipe.ResistivityStartTimeSeconds = Recipe.ResistivityStartTimeSeconds;
+                        //recipe.ResistivityMegaOhms = Recipe.ResistivityMegaOhms;
+                        //recipe.N2ChargeTimeSeconds = Recipe.N2ChargeTimeSeconds;
+                        //recipe.DumpTimeSeconds = Recipe.DumpTimeSeconds;
+
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<QdrRecipe>(ENGINEERING, recipe.Ppid, "qdr", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
+
+        /// <summary>
         /// 检验合法性
         /// </summary>
         /// <param name="editType"></param>

+ 67 - 3
CyberX8_MainPages/ViewModels/RdsRecipeViewModel.cs

@@ -3,11 +3,12 @@ using Aitex.Core.UI.Dialog;
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
 using Caliburn.Micro.Core;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_Core;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -127,7 +128,7 @@ namespace CyberX8_MainPages.ViewModels
             CreateCommand = new DelegateCommand<object>(CreateAction);
             EditCommand = new DelegateCommand<object>(EditAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
-
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             ChemReplenEnableTrueCommand = new DelegateCommand<object>(ChemReplenEnableTrueAction);
             ChemReplenEnableFalseCommand = new DelegateCommand<object>(ChemReplenEnableFalseAction);
             CurrentBasedTrueCommand = new DelegateCommand<object>(CurrentBasedTrueAction);
@@ -331,6 +332,69 @@ namespace CyberX8_MainPages.ViewModels
                 }
             }
         }
+        /// <summary>
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            RdsRecipe recipe = new RdsRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new RdsRecipe();
+
+                        //复制属性
+                        //recipe.AutoDoseEnable = Recipe.AutoDoseEnable;
+                        //recipe.AutoCurrentBased = Recipe.AutoCurrentBased;
+                        //recipe.AutoDoseFrequency = Recipe.AutoDoseFrequency;
+                        //recipe.AutoTimeBased = Recipe.AutoTimeBased;
+                        //recipe.AutoDoseIdleStartTime = Recipe.AutoDoseIdleStartTime;
+                        //recipe.ReplenCurrentBased = Recipe.ReplenCurrentBased;
+                        //recipe.ReplenCurrentBasedRate = Recipe.ReplenCurrentBasedRate;
+                        //recipe.ReplenEnable = Recipe.ReplenEnable;
+                        //recipe.ReplenNoCircFactor = Recipe.ReplenNoCircFactor;
+                        //recipe.ReplenTimeBased = Recipe.ReplenTimeBased;
+                        //recipe.ReplenTimeBasedRate = Recipe.ReplenTimeBasedRate;
+                        recipe = (RdsRecipe)PropertyUtil.Clone(Recipe);
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<RdsRecipe>(ENGINEERING, recipe.Ppid, "rds", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
+
         private bool CheckValid(bool editType)
         {
             //在ReplenEnable false时跳过检验项

+ 105 - 2
CyberX8_MainPages/ViewModels/ResRecipeViewModel.cs

@@ -3,11 +3,12 @@ using Aitex.Core.UI.Dialog;
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
 using Caliburn.Micro.Core;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_Core;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -116,6 +117,8 @@ namespace CyberX8_MainPages.ViewModels
         [IgnorePropertyChange]
         public ICommand SaveRecipeCommand { get; private set; }
         [IgnorePropertyChange]
+        public ICommand SaveAsRecipeCommand { get; private set; }
+        [IgnorePropertyChange]
         public ICommand DIReplenEnableTrueCommand { get; private set; }
         [IgnorePropertyChange]
         public ICommand DIReplenEnableFalseCommand { get; private set; }
@@ -141,6 +144,7 @@ namespace CyberX8_MainPages.ViewModels
             CreateCommand = new DelegateCommand<object>(CreateAction);
             EditCommand = new DelegateCommand<object>(EditAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             DIReplenEnableTrueCommand = new DelegateCommand<object>(EnableTrueAction);
             DIReplenEnableFalseCommand = new DelegateCommand<object>(EnableFalseAction);
             ANDIReplenEnableTrueCommand = new DelegateCommand<object>(ANEnableTrueAction);
@@ -301,7 +305,106 @@ namespace CyberX8_MainPages.ViewModels
                 }
             }
         }
+        /// <summary>
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            ResRecipe recipe = new ResRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new ResRecipe();
+
+                        //recipe.IdleTime = Recipe.IdleTime;
+                        //recipe.Charge = Recipe.Charge;
+                        //recipe.Cycles = Recipe.Cycles;
+                        //recipe.StartTime = Recipe.StartTime;
+                        //recipe.ChemistryVendor = Recipe.ChemistryVendor;
+                        //recipe.Metal = Recipe.Metal;
+                        //recipe.DIReplenEnable = Recipe.DIReplenEnable;
+                        //recipe.DIReplenTimeRate = Recipe.DIReplenTimeRate;
+                        //recipe.DIReplenCurrentRate = Recipe.DIReplenCurrentRate;
+                        //recipe.PHErrorLow = Recipe.PHErrorLow;
+                        //recipe.PHErrorHigh = Recipe.PHErrorHigh;
+                        //recipe.CALevelErrorHigh = Recipe.CALevelErrorHigh;
+                        //recipe.CALevelErrorLow = Recipe.CALevelErrorLow;
+                        //recipe.ReservoirCALevel = Recipe.ReservoirCALevel;
+                        //recipe.CAFlowSetPoint = Recipe.CAFlowSetPoint;
+                        //recipe.CAFlowRateWarningLow = Recipe.CAFlowRateWarningLow;
+                        //recipe.CAFlowRateErrorLow = Recipe.CAFlowRateErrorLow;
+                        //recipe.IdleFlowEnable = Recipe.IdleFlowEnable;
+                        //recipe.TemperatureErrorHigh = Recipe.TemperatureErrorHigh;
+                        //recipe.TemperatureErrorLow = Recipe.TemperatureErrorLow;
+                        //recipe.TemperatureSetPoint = Recipe.TemperatureSetPoint;
+                        //recipe.TemperatureWarningHigh = Recipe.TemperatureWarningHigh;
+                        //recipe.TemperatureWarningLow = Recipe.TemperatureWarningLow;
+                        //recipe.ANDIReplenEnable = Recipe.ANDIReplenEnable;
+                        //recipe.ANDIReplenCurrentRate = Recipe.ANDIReplenCurrentRate;
+                        //recipe.ANDIReplenTimeRate = Recipe.ANDIReplenTimeRate;
+                        //recipe.ANFlowRateErrorLow = Recipe.ANFlowRateErrorLow;
+                        //recipe.ANFlowRateWarningLow = Recipe.ANFlowRateWarningLow;
+                        //recipe.ANFlowSetPoint = Recipe.ANFlowSetPoint;
+                        //recipe.ANLevelErrorHigh = Recipe.ANLevelErrorHigh;
+                        //recipe.ANLevelErrorLow = Recipe.ANLevelErrorLow;
+                        //recipe.ANLevelWarningLow = Recipe.ANLevelWarningLow;
+                        //recipe.ReservoirANLevel = Recipe.ReservoirANLevel;
+                        //recipe.CrossDoseCurrentRate = Recipe.CrossDoseCurrentRate;
+                        //recipe.CrossDoseTimeRate = Recipe.CrossDoseTimeRate;
+                        //recipe.CurrentBased = Recipe.CurrentBased;
+                        //recipe.TimeBased = Recipe.TimeBased;
+                        //recipe.BurnInEnable = Recipe.BurnInEnable;
+                        //recipe.BurnInTime = Recipe.BurnInTime;
+                        //recipe.BurnInCurrent = Recipe.BurnInCurrent;
+                        //recipe.BurnInCycles = Recipe.BurnInCycles;
+                        //recipe.BurnInCurrentLimitEnable = Recipe.BurnInCurrentLimitEnable;
+                        //recipe.BurnInMinCurrentLimit = Recipe.BurnInMinCurrentLimit;
+                        //recipe.CMMEnable = Recipe.CMMEnable;
+                        //recipe.CMMCurrentSetPoint = Recipe.CMMCurrentSetPoint;
+                        //recipe.CMMCurrentFaultPercent = Recipe.CMMCurrentFaultPercent;
+                        //recipe.CMMCurrentWarningPercent = Recipe.CMMCurrentWarningPercent;
+                        //recipe.CMMMinVoltage = Recipe.CMMMinVoltage;
 
+                        //recipe.BurnInStartTime = Recipe.BurnInStartTime; //值类型,不影响Recipe
+                        recipe = (ResRecipe)PropertyUtil.Clone(Recipe);
+
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<ResRecipe>(ENGINEERING, recipe.Ppid, "res", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
         private void EnableTrueAction(object param)
         {
             Recipe.DIReplenEnable = true;

+ 66 - 2
CyberX8_MainPages/ViewModels/SequenceRecipeViewModel.cs

@@ -1,9 +1,10 @@
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -322,6 +323,7 @@ namespace CyberX8_MainPages.ViewModels
             MoveUpCommand=new DelegateCommand<object>(MoveUpAction);
             MoveDownCommand=new DelegateCommand<object>(MoveDownAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             GetAvaibleRecipeType();
             GetComboxLst();
             InitializeProprtyValidResultDictionary();
@@ -575,6 +577,68 @@ namespace CyberX8_MainPages.ViewModels
                 }
             }
         }
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            SequenceRecipe recipe = new SequenceRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new SequenceRecipe();
+                        //赋值属性
+
+                        //recipe.AlignmentAngle = Recipe.AlignmentAngle;
+                        //recipe.CrsType = Recipe.CrsType;
+                        //recipe.FiducialType = Recipe.FiducialType;
+                        //recipe.LastSingleWaferToSideB = Recipe.LastSingleWaferToSideB;
+                        //recipe.SubstrateSize = Recipe.SubstrateSize;
+                        //recipe.SequenceType = Recipe.SequenceType;
+
+                        //recipe.Recipes = new List<string>();
+                        //foreach (var item in Recipe.Recipes)
+                        //{
+                        //    recipe.Recipes.Add(item); 
+                        //}
+                        recipe = (SequenceRecipe)PropertyUtil.Clone(Recipe);
+
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<SequenceRecipe>(ENGINEERING, recipe.Ppid, "seq", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
         /// <summary>
         /// 检验合法性
         /// </summary>

+ 74 - 2
CyberX8_MainPages/ViewModels/SrdRecipeViewModel.cs

@@ -4,11 +4,12 @@ using Aitex.Core.UI.Dialog;
 using Aitex.Core.UI.MVVM;
 using Aitex.Core.Utilities;
 using Caliburn.Micro.Core;
-using MECF.Framework.Common.DataCenter;
-using MECF.Framework.Common.RecipeCenter;
 using CyberX8_Core;
 using CyberX8_MainPages.PMs;
 using CyberX8_Themes.UserControls;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Utilities;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
@@ -156,6 +157,7 @@ namespace CyberX8_MainPages.ViewModels
             CreateCommand = new DelegateCommand<object>(CreateAction);
             EditCommand = new DelegateCommand<object>(EditAction);
             SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
+            SaveAsRecipeCommand = new DelegateCommand<object>(SaveAsAction);
             InitializeProprtyValidResultDictionary();
         }
         /// <summary>
@@ -317,6 +319,76 @@ namespace CyberX8_MainPages.ViewModels
             }
         }
         /// <summary>
+        /// 另存为
+        /// </summary>
+        /// <param name="param"></param>
+        private void SaveAsAction(object param)
+        {
+            if (Recipe == null)
+            {
+                MessageBox.Show("Select a Recipe first", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                return;
+            }
+            SrdRecipe recipe = new SrdRecipe();
+            if (CheckValid(_isEdit))
+            {
+                RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
+                if (recipeNameDialog.ShowDialog().Value)
+                {
+                    if (!CheckNameExist(recipeNameDialog.RecipeName))
+                    {
+                        recipe = new SrdRecipe();
+
+                        //属性复制
+                        //recipe.BackN2DryTime = Recipe.BackN2DryTime;
+                        //recipe.BackRinseTime = Recipe.BackRinseTime;
+                        //recipe.DivertPlusPoolDelay = Recipe.DivertPlusPoolDelay;
+                        //recipe.DrySpeed = Recipe.DrySpeed;
+                        //recipe.ExhaustFanDelay = Recipe.ExhaustFanDelay;
+                        //recipe.FlowCheckDelay = Recipe.FlowCheckDelay;
+                        //recipe.FrontDivertTime = Recipe.FrontDivertTime;
+                        //recipe.FrontPoolTime = Recipe.FrontPoolTime;
+                        //recipe.FrontRinseTime = Recipe.FrontRinseTime;
+                        //recipe.MaxDivertPlusPoolPressure = Recipe.MaxDivertPlusPoolPressure;
+                        //recipe.MaxWashFlow = Recipe.MaxWashFlow;
+                        //recipe.MaxWashPressure = Recipe.MaxWashPressure;
+                        //recipe.MinDivertPlusPoolFlow = Recipe.MinDivertPlusPoolFlow;
+                        //recipe.MinWashFlow = Recipe.MinWashFlow;
+                        //recipe.MinWaterPressure = Recipe.MinWaterPressure;
+                        //recipe.PostN2DryTime = Recipe.PostN2DryTime;
+                        //recipe.PreN2DryTime = Recipe.PreN2DryTime;
+                        //recipe.RinseSpeed = Recipe.RinseSpeed;
+                        recipe = (SrdRecipe)PropertyUtil.Clone(Recipe);
+
+
+                        recipe.CreateDate = DateTime.Now;
+                        recipe.Ppid = recipeNameDialog.RecipeName;
+                        recipe.Description = recipeNameDialog.RecipeDescription;
+                    }
+                    else if (recipeNameDialog.RecipeName != null)
+                    {
+                        MessageBox.Show("Name can not be Null", "Create Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+                    else
+                    {
+                        return;
+                    }
+                }
+                try
+                {
+                    _uiRecipeManager.SaveRecipe<SrdRecipe>(ENGINEERING, recipe.Ppid, "srd", recipe);
+                    LoadRecipeData();
+                    MessageBox.Show("Save As Recipe Success", "SaveAs Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
+                    Enable = false;
+                }
+                catch (Exception ex)
+                {
+                    MessageBox.Show(ex.Message, "Save As Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
+                }
+            }
+        }
+        /// <summary>
         /// 检验合法性
         /// </summary>
         /// <param name="editType"></param>

+ 3 - 2
CyberX8_MainPages/Views/DepRecipeView.xaml

@@ -55,13 +55,14 @@
                 <RowDefinition/>
                 <RowDefinition Height="70"></RowDefinition>
             </Grid.RowDefinitions>
-            <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+            <Grid Grid.Row="0">
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                 </Grid.ColumnDefinitions>
-                <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
             </Grid>
 
             <GroupBox Header="Total Time" Grid.Row="1" HorizontalAlignment="Left" Margin="40,0,0,0" Width="200">

+ 3 - 2
CyberX8_MainPages/Views/HvdRecipeView.xaml

@@ -73,13 +73,14 @@
                 <RowDefinition/>
                 <RowDefinition Height="70"></RowDefinition>
             </Grid.RowDefinitions>
-            <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+            <Grid Grid.Row="0" >
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                 </Grid.ColumnDefinitions>
-                <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
             </Grid>
 
         </Grid>

+ 3 - 2
CyberX8_MainPages/Views/PwtRecipeView.xaml

@@ -90,13 +90,14 @@
                 <RowDefinition/>
                 <RowDefinition Height="70"></RowDefinition>
             </Grid.RowDefinitions>
-            <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+            <Grid Grid.Row="0" >
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                 </Grid.ColumnDefinitions>
-                <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
             </Grid>
 
         </Grid>

+ 3 - 2
CyberX8_MainPages/Views/QdrRecipeView.xaml

@@ -53,13 +53,14 @@
                 <RowDefinition/>
                 <RowDefinition Height="70"></RowDefinition>
             </Grid.RowDefinitions>
-            <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+            <Grid Grid.Row="0">
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                 </Grid.ColumnDefinitions>
-                <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
             </Grid>
         </Grid>
 

+ 3 - 2
CyberX8_MainPages/Views/RdsRecipeView.xaml

@@ -53,13 +53,14 @@
                 <Grid.RowDefinitions>
                     <RowDefinition Height="70"></RowDefinition>
                 </Grid.RowDefinitions>
-                <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+                <Grid Grid.Row="0" >
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition/>
                         <ColumnDefinition/>
                         <ColumnDefinition/>
                     </Grid.ColumnDefinitions>
-                    <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                    <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                    <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
                 </Grid>
 
             </Grid>

+ 3 - 2
CyberX8_MainPages/Views/ResRecipeView.xaml

@@ -54,13 +54,14 @@
                 <Grid.RowDefinitions>
                     <RowDefinition Height="70"></RowDefinition>
                 </Grid.RowDefinitions>
-                <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+                <Grid Grid.Row="0" >
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition/>
                         <ColumnDefinition/>
                         <ColumnDefinition/>
                     </Grid.ColumnDefinitions>
-                    <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                    <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                    <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
                 </Grid>
 
             </Grid>

+ 3 - 2
CyberX8_MainPages/Views/SequenceRecipeView.xaml

@@ -109,13 +109,14 @@
                 <RowDefinition Height="70"></RowDefinition>
                 <RowDefinition/>
             </Grid.RowDefinitions>
-            <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+            <Grid Grid.Row="0" >
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                 </Grid.ColumnDefinitions>
-                <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
             </Grid>
             <Grid Grid.Row="3">
                 <Grid.RowDefinitions>

+ 3 - 2
CyberX8_MainPages/Views/SrdRecipeView.xaml

@@ -103,13 +103,14 @@
                 <RowDefinition/>
                 <RowDefinition Height="70"></RowDefinition>
             </Grid.RowDefinitions>
-            <Grid Grid.Row="0" IsEnabled="{Binding Enable}">
+            <Grid Grid.Row="0" >
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                     <ColumnDefinition/>
                 </Grid.ColumnDefinitions>
-                <Button Grid.Column="0" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="0" IsEnabled="{Binding Enable}" Style="{StaticResource SysBtnStyle}"  Content="Save" Height="35" Width="100" Command="{Binding SaveRecipeCommand}"></Button>
+                <Button Grid.Column="1" Style="{StaticResource SysBtnStyle}"  Content="SaveAs" Height="35" Width="100" Command="{Binding SaveAsRecipeCommand}"></Button>
             </Grid>
             <Grid Grid.Row="2">
                 <Grid.ColumnDefinitions>

+ 1 - 1
CyberX8_RT/Config/Devices/PowerSupplierCfg-Simulator.xml

@@ -15,7 +15,7 @@
   
   <PowerSupplierDeviceConfig Name="Power5" IpAddress="127.0.0.1" Port="824" Type="0" SendTimeout="2000" RecvTimeout="2000"> 
     <Device Name="Power5-1" Address="1"  VoltageUnitSetScale ="1000" UnitSetScale="1000" UnitScale="10000" />
-  </PowerSupplierDeviceConfig>
+  </PowerSupplierDeviceConfig>s
   
   <PowerSupplierDeviceConfig Name="Power6" IpAddress="127.0.0.1" Port="825" Type="0" SendTimeout="2000" RecvTimeout="2000"> 
     <Device Name="Power6-1" Address="1"  VoltageUnitSetScale ="1000" UnitSetScale="1000" UnitScale="10000" />

+ 1 - 1
CyberX8_RT/Devices/Reservoir/StandardHotReservoirDevice.cs

@@ -424,7 +424,7 @@ namespace CyberX8_RT.Devices.Reservoir
             //DIReplen总阀未开关闭槽体DIReplen;未初始化关闭槽体DIReplen
             ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(Module);
             SystemFacilities systemFacility = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
-            if (!systemFacility.DIReplenEnable || (reservoirEntity == null || !reservoirEntity.IsInitialized))
+            if (systemFacility!=null && (!systemFacility.DIReplenEnable || (reservoirEntity == null || !reservoirEntity.IsInitialized)))
             {
                 if (IsDireplenOn) DIReplenOff("", null);
             }

+ 1 - 0
Framework/Common/Common.csproj

@@ -569,6 +569,7 @@
     <Compile Include="Utilities\CommonFunction.cs" />
     <Compile Include="Utilities\DataTypeUtil.cs" />
     <Compile Include="Utilities\IOVariableDictionaryUtil.cs" />
+    <Compile Include="Utilities\PropertyUtil.cs" />
     <Compile Include="Utilities\SerialPortUtil.cs" />
     <Compile Include="WaferHolder\WaferHolderBufferInfo.cs" />
     <Compile Include="WaferHolder\WaferHolderInfo.cs" />

+ 157 - 0
Framework/Common/Utilities/PropertyUtil.cs

@@ -0,0 +1,157 @@
+using CyberX8_Core;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MECF.Framework.Common.Utilities
+{
+    public class PropertyUtil
+    {
+        public static object Clone(object source)
+        {
+            Type type = source.GetType();
+            object target = System.Activator.CreateInstance(type);
+            BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;
+            PropertyInfo[] propertyInfos = type.GetProperties(bindingFlags);
+            foreach (PropertyInfo property in propertyInfos)
+            {
+                if (!property.CanWrite) continue;
+                //check whether property type is value type, enum or string type
+                if (property.PropertyType.IsPrimitive || property.PropertyType.IsEnum || property.PropertyType == typeof(string))
+                {
+                    property.SetValue(target, property.GetValue(source, null), null);
+                }
+                else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
+                {
+                    //Include List and Dictionary and......
+                    if (property.PropertyType.IsGenericType)
+                    {
+                        var cloneObj = Activator.CreateInstance(property.PropertyType);
+
+                        var addMethod = property.PropertyType.GetMethod("Add", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+
+                        Debug.Assert(null != addMethod);
+
+                        var currentValues = property.GetValue(source, null) as IEnumerable;
+                        if (currentValues == null)
+                        {
+                            property.SetValue(target, null, null);
+                        }
+                        else
+                        {
+                            if (cloneObj is IDictionary)
+                            {
+                                cloneObj = cloneObj as IDictionary;
+                                foreach (var currentValue in currentValues)
+                                {
+                                    var propInfoKey = currentValue.GetType().GetProperty("Key");
+                                    var propInfoValue = currentValue.GetType().GetProperty("Value");
+                                    if (propInfoKey != null && propInfoValue != null)
+                                    {
+                                        var keyValue = propInfoKey.GetValue(currentValue, null);
+                                        var valueValue = propInfoValue.GetValue(currentValue, null);
+
+                                        object finalKeyValue, finalValueValue;
+
+                                        //Get finalKeyValue
+                                        var currentKeyType = keyValue.GetType();
+                                        if (currentKeyType.IsPrimitive || currentKeyType.IsEnum || currentKeyType == typeof(string))
+                                        {
+                                            finalKeyValue = keyValue;
+                                        }
+                                        else
+                                        {
+                                            //Reference type
+                                            var copyObj = Clone(keyValue);
+                                            finalKeyValue = copyObj;
+                                        }
+
+                                        //Get finalValueValue
+                                        var currentValueType = valueValue.GetType();
+                                        if (currentValueType.IsPrimitive || currentValueType.IsEnum || currentValueType == typeof(string))
+                                        {
+                                            finalValueValue = valueValue;
+                                        }
+                                        else
+                                        {
+                                            //Reference type
+                                            var copyObj = Clone(valueValue);
+                                            finalValueValue = copyObj;
+                                        }
+
+                                        addMethod.Invoke(cloneObj, new[] { finalKeyValue, finalValueValue });
+                                    }
+                                }
+                                property.SetValue(target, cloneObj, null);
+                            }
+                            //Common IList type
+                            else
+                            {
+                                foreach (var currentValue in currentValues)
+                                {
+                                    var currentType = currentValue.GetType();
+                                    if (currentType.IsPrimitive || currentType.IsEnum || currentType == typeof(string))
+                                    {
+                                        addMethod.Invoke(cloneObj, new[] { currentValue });
+                                    }
+                                    else
+                                    {
+                                        //Reference type
+                                        var copyObj = Clone(currentValue);
+                                        addMethod.Invoke(cloneObj, new[] { copyObj });
+                                    }
+                                }
+                                property.SetValue(target, cloneObj, null);
+                            }
+                        }
+                    }
+                    //Array type
+                    else
+                    {
+                        var currentValues = property.GetValue(source, null) as Array;
+                        if (null == currentValues)
+                        {
+                            property.SetValue(target, null, null);
+                        }
+                        else
+                        {
+                            var cloneObj = Activator.CreateInstance(property.PropertyType, currentValues.Length) as Array;
+                            var arrayList = new ArrayList();
+                            for (var i = 0; i < currentValues.Length; i++)
+                            {
+                                var currentType = currentValues.GetValue(i).GetType();
+                                if (currentType.IsPrimitive || currentType.IsEnum || currentType == typeof(string))
+                                {
+                                    arrayList.Add(currentValues.GetValue(i));
+                                }
+                                else
+                                {
+                                    //Reference type
+                                    var copyObj = Clone(currentValues.GetValue(i));
+                                    arrayList.Add(copyObj);
+                                }
+                            }
+                            arrayList.CopyTo(cloneObj, 0);
+                            property.SetValue(target, cloneObj, null);
+                        }
+                    }
+                }
+                else if (property.PropertyType.IsClass)
+                {
+                    object inner = property.GetValue(source, null);
+                    property.SetValue(target, Clone(inner), null);
+                }
+                else
+                {
+                    property.SetValue(target, property.GetValue(source, null), null);
+                }
+            }
+            return target;
+        }
+    }
+}