Переглянути джерело

1.将rt向ui传递robot状态放在线程安全队列,避免数据包丢失
2.给Recipe修改界面添加二级目录,目录名为Recipe Type名
3.PM界面与Sequence选择recipe,不再show出所有recipe,只show出对应Process/Clean Recipe

lixiang 1 рік тому
батько
коміт
f53a5428e6

+ 1 - 0
Venus/Framework/Common/Common.csproj

@@ -219,6 +219,7 @@
     <Compile Include="CommonData\LeakCheckResultItem.cs" />
     <Compile Include="CommonData\LeakCheckResultManager.cs" />
     <Compile Include="CommonData\NotifiableData.cs" />
+    <Compile Include="CommonData\RobotAnimationData.cs" />
     <Compile Include="CommonData\RobotMoveInfo.cs" />
     <Compile Include="CommonData\SorterDefines\DeviceState.cs" />
     <Compile Include="CommonData\SorterDefines\FoupClampState.cs" />

+ 23 - 0
Venus/Framework/Common/CommonData/RobotAnimationData.cs

@@ -0,0 +1,23 @@
+using Aitex.Sorter.Common;
+using MECF.Framework.Common.Equipment;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MECF.Framework.Common.CommonData
+{
+    public class RobotAnimationData
+    {
+        public RobotAnimationData(RobotAction action, Hand hand, ModuleName target)
+        {
+            Action = action;
+            Hand = hand;
+            Target = target;
+        }
+        public RobotAction Action { get; set; }
+        public Hand Hand { get; set; }
+        public ModuleName Target { get; set; }
+    }
+}

+ 1 - 1
Venus/Framework/Common/RecipeCenter/IRecipeService.cs

@@ -105,7 +105,7 @@ namespace MECF.Framework.Common.RecipeCenter
 
         #region extended recipe interface
         [OperationContract]
-        string LoadRecipeByPath(string pathName, string recipeName);
+        string LoadRecipeByPath(string path);
 
         [OperationContract]
         Tuple<string, string> LoadRunTimeRecipeInfoByPath(string pathName);

+ 49 - 11
Venus/Framework/Common/RecipeCenter/RecipeFileManager.cs

@@ -321,16 +321,50 @@ namespace Aitex.Core.RT.RecipeCenter
                     rcp = fs.ReadToEnd();
                     fs.Close();
                 }
-                //if (needValidation)
-                //{
-                //    List<string> reason;
-                //    if (!ValidateRecipe(chamberId, recipeName, rcp, out reason))
-                //    {
-                //        rcp = string.Empty;
-
-                //        LOG.Write("校验recipe file 出错, " + string.Join(",", reason.ToArray()));
-                //    }
-                //}
+            }
+            catch (Exception ex)
+            {
+                LOG.WriteExeption($"load recipe file failed, {recipeName}", ex);
+                rcp = string.Empty;
+            }
+            return rcp;
+        }
+        public string LoadRecipeByPath(string path)
+        {
+            string rcp = string.Empty;
+            try
+            {
+                using (StreamReader fs = new StreamReader(path))
+                {
+                    rcp = fs.ReadToEnd();
+                    fs.Close();
+                }
+            }
+            catch (Exception ex)
+            {
+               // LOG.WriteExeption($"load recipe file failed, {recipeName}", ex);
+                rcp = string.Empty;
+            }
+            return rcp;
+        }
+        /// <summary>
+        /// This method will be invoked by two places:
+        /// (1) Load a recipe from server to GUI for editing (do not need validation when loading, do validation when saving);
+        /// (2) Load a recipe from recipe engine to run process(always do a validation before run recipe);
+        /// </summary>
+        /// <param name="recipeName"></param>
+        /// <param name="needValidation">indicate whether a recipe format validation is needed or not</param>
+        /// <returns></returns>
+        public string LoadRecipe(string chamberId, string recipeName, bool needValidation,string type)
+        {
+            string rcp = string.Empty;
+            try
+            {
+                using (StreamReader fs = new StreamReader(GenerateRecipeFilePath2(chamberId,type, recipeName)))
+                {
+                    rcp = fs.ReadToEnd();
+                    fs.Close();
+                }
             }
             catch (Exception ex)
             {
@@ -537,6 +571,10 @@ namespace Aitex.Core.RT.RecipeCenter
         {
             return getRecipeDirPath(chamId) + recipeName + ".rcp";
         }
+        private string GenerateRecipeFilePath2(string chamId,  string type,string recipeName)
+        {
+            return getRecipeDirPath(chamId) +type+"\\"+ recipeName + ".rcp";
+        }
         private string GenerateSequenceFilePath(string chamId, string recipeName)
         {
             return getRecipeDirPath(chamId) + recipeName + ".seq";
@@ -655,7 +693,7 @@ namespace Aitex.Core.RT.RecipeCenter
             bool ret = true;
             try
             {
-                var path = GenerateRecipeFilePath(chamId, recipeName);
+                var path = GenerateRecipeFilePath2(chamId, type, recipeName);
 
                 if (!_rcpContext.EnableEdit(path))
                     return false;

+ 2 - 2
Venus/Framework/Common/RecipeCenter/RecipeService.cs

@@ -287,9 +287,9 @@ namespace MECF.Framework.Common.RecipeCenter
 
         #region extended recipe interface
 
-        public string LoadRecipeByPath(string pathName, string recipeName)
+        public string LoadRecipeByPath(string path)
         {
-            return RecipeFileManager.Instance.LoadRecipe(pathName, recipeName, false);
+            return RecipeFileManager.Instance.LoadRecipeByPath(path);
         }
         public bool DeleteRecipeByPath(string pathName, string recipeName)
         {

+ 2 - 2
Venus/Framework/Common/RecipeCenter/RecipeServiceClient.cs

@@ -220,10 +220,10 @@ namespace MECF.Framework.Common.RecipeCenter
             return result;
         }
         #region extended recipe interface
-        public string LoadRecipeByPath(string pathName, string recipeName)
+        public string LoadRecipeByPath(string path)
         {
             string result = null;
-            Invoke(svc => { result = svc.LoadRecipeByPath(pathName, recipeName); });
+            Invoke(svc => { result = svc.LoadRecipeByPath(path); });
             return result;
         }
 

+ 4 - 0
Venus/Venus_MainPages/PMS/UiRecipeManager.cs

@@ -11,6 +11,10 @@ namespace Venus_MainPages.PMs
         {
             return RecipeClient.Instance.Service.LoadRecipe(ModuleNameString.ToEnum(chamId), receipeName);
         }
+        public string LoadRecipeByPath(string path)
+        {
+            return RecipeClient.Instance.Service.LoadRecipeByPath(path);
+        }
 
         public Tuple<string, string> LoadRunTimeRecipeInfo(string chamId)
         {

+ 1 - 1
Venus/Venus_MainPages/ViewModels/OperationOverViewModel.cs

@@ -453,7 +453,7 @@ namespace Venus_MainPages.ViewModels
         public OperationOverViewModel()
         {
             DispatcherTimer timer = new DispatcherTimer();
-            timer.Interval = TimeSpan.FromSeconds(0.01);
+            timer.Interval = TimeSpan.FromSeconds(0.1);
             timer.Tick += Timer_Tick;
             timer.Start();
 

+ 4 - 4
Venus/Venus_MainPages/ViewModels/OverKepler2200AViewModel.cs

@@ -1051,7 +1051,7 @@ namespace Venus_MainPages.ViewModels
 
             ModuleName = "PMA";
             
-            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
+            //CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
 
             DispatcherTimer timer = new DispatcherTimer();
             timer.Interval = TimeSpan.FromSeconds(0.5);
@@ -1355,7 +1355,7 @@ namespace Venus_MainPages.ViewModels
         }
         private void OnLoadRecipe()
         {
-            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
+            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, "Process")).ToList();
         }
 
         //private async void OnHV()
@@ -1393,7 +1393,7 @@ namespace Venus_MainPages.ViewModels
                 return;
             }
             ClearData();
-            var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, recipeName + ".rcp");
+            var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, "Process", recipeName + ".rcp");
             CurrentRecipe = Recipe.Load(File.ReadAllText(recipePath));
             InvokeClient.Instance.Service.DoOperation($"{ModuleName}.{RtOperation.RunRecipe}",recipeName);
         }
@@ -1634,7 +1634,7 @@ namespace Venus_MainPages.ViewModels
                 CurrentRecipeResult = CommonFunction.GetValue<RecipeResult>(RtDataValues, $"{ModuleName}.CurrentRecipeResult");
                 if (CurrentRecipeResult.RecipeStepNumber != null && CurrentRecipeResult.RecipeStepNumber != currentRecipeNumber)
                 {
-                    var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, CurrentRecipeResult.RecipeName + ".rcp");
+                    var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName,"Process", CurrentRecipeResult.RecipeName + ".rcp");
                     CurrentRecipe = Recipe.Load(File.ReadAllText(recipePath));
                     CurrentRecipeStep = CurrentRecipe.Steps[Convert.ToInt32(CurrentRecipeResult.RecipeStepNumber) - 1];
                 }

+ 4 - 4
Venus/Venus_MainPages/ViewModels/OverKepler2300ViewModel.cs

@@ -1096,7 +1096,7 @@ namespace Venus_MainPages.ViewModels
 
             ModuleName = "PMA";
 
-            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
+            //CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
 
             DispatcherTimer timer = new DispatcherTimer();
             timer.Interval = TimeSpan.FromSeconds(0.5);
@@ -1347,7 +1347,7 @@ namespace Venus_MainPages.ViewModels
         }
         private void OnLoadRecipe()
         {
-            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
+            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, "Process")).ToList();
         }
 
         private void OnHVSet()
@@ -1365,7 +1365,7 @@ namespace Venus_MainPages.ViewModels
                 return;
             }
             ClearData();
-            var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, recipeName + ".rcp");
+            var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, "Process", recipeName + ".rcp");
             CurrentRecipe = Recipe.Load(File.ReadAllText(recipePath));
             InvokeClient.Instance.Service.DoOperation($"{ModuleName}.{RtOperation.RunRecipe}", recipeName);
         }
@@ -1640,7 +1640,7 @@ namespace Venus_MainPages.ViewModels
                 CurrentRecipeResult = CommonFunction.GetValue<RecipeResult>(RtDataValues, $"{ModuleName}.CurrentRecipeResult");
                 if (CurrentRecipeResult.RecipeStepNumber != null && CurrentRecipeResult.RecipeStepNumber != currentRecipeNumber)
                 {
-                    var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, CurrentRecipeResult.RecipeName + ".rcp");
+                    var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes","Process", ModuleName, CurrentRecipeResult.RecipeName + ".rcp");
                     CurrentRecipe = Recipe.Load(File.ReadAllText(recipePath));
                     CurrentRecipeStep = CurrentRecipe.Steps[Convert.ToInt32(CurrentRecipeResult.RecipeStepNumber) - 1];
                 }

+ 3 - 3
Venus/Venus_MainPages/ViewModels/OverVenusViewModel.cs

@@ -1057,7 +1057,7 @@ namespace Venus_MainPages.ViewModels
 
             ModuleName = "PMA";
 
-            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
+            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, "Process")).ToList();
 
             DispatcherTimer timer = new DispatcherTimer();
             timer.Interval = TimeSpan.FromSeconds(0.5);
@@ -1356,7 +1356,7 @@ namespace Venus_MainPages.ViewModels
         }
         private void OnLoadRecipe()
         {
-            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList();
+            CurrentModuleRecipes = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, "Process")).ToList();
         }
 
         private void OnHV()
@@ -1395,7 +1395,7 @@ namespace Venus_MainPages.ViewModels
                 return;
             }
             ClearData();
-            var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, recipeName + ".rcp");
+            var recipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName,"Process", recipeName + ".rcp");
             CurrentRecipe = Recipe.Load(File.ReadAllText(recipePath));
             InvokeClient.Instance.Service.DoOperation($"{ModuleName}.{RtOperation.RunRecipe}", recipeName);
         }

+ 145 - 101
Venus/Venus_MainPages/ViewModels/RecipeViewModel.cs

@@ -18,6 +18,7 @@ using System.Threading;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
+using System.Windows.Documents;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Xml;
@@ -29,6 +30,7 @@ using Venus_MainPages.Views;
 using Venus_Themes.UserControls;
 using Venus_Unity;
 using WPF.Themes.UserControls;
+using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
 using RecipeStep = Venus_Core.RecipeStep;
 
 namespace Venus_MainPages.ViewModels
@@ -74,7 +76,7 @@ namespace Venus_MainPages.ViewModels
 
         private List<string> moduleList = new List<string> ();
         TreeViewFileItem selectedItem;
-
+        private string typeFolder="";
         #endregion
 
         #region  属性
@@ -173,36 +175,6 @@ namespace Venus_MainPages.ViewModels
 
                     recipeStep = new RecipeStep();
                     recipeStep.LstUnit = RecipeUnity.GetAllUnits(currentChamber,CurrentRecipe.Header.Type);
-                    //switch (currentChamber)
-                    //{
-                    //    case JetChamber.Venus:
-                    //        recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
-                    //        recipeStep.LstUnit.Add(new TCPUnit());
-                    //        recipeStep.LstUnit.Add(new BiasUnit());
-                    //        recipeStep.LstUnit.Add(new GasControlUnit());
-                    //        recipeStep.LstUnit.Add(new ESCHVUnit());
-                    //        recipeStep.LstUnit.Add(new ProcessKitUnit());
-                    //        break;
-                    //    case JetChamber.Kepler2300:
-                    //        recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
-                    //        recipeStep.LstUnit.Add(new TCPUnit());
-                    //        recipeStep.LstUnit.Add(new BiasUnit());
-                    //        recipeStep.LstUnit.Add(new GasControlUnit());
-                    //        recipeStep.LstUnit.Add(new ProcessKitUnit());
-                    //        break;
-
-                    //    case JetChamber.Kepler2200A:
-                    //        recipeStep.LstUnit.Add(new Kepler2200GasControlUnit());
-
-                    //        recipeStep.LstUnit.Add(new HeaterUnit());
-                    //        recipeStep.LstUnit.Add(new Kepler2200RFUnit());
-
-
-
-
-
-                    //        break;
-                    //}
 
                     CurrentRecipe.Steps.Insert(index - 1, recipeStep);
 
@@ -244,7 +216,6 @@ namespace Venus_MainPages.ViewModels
                 return;
             }
 
-            //JetChamber jetChamber = JetChamber.None;
             string moduleName = "";
             switch (obj.ToString())
             {
@@ -285,15 +256,17 @@ namespace Venus_MainPages.ViewModels
                         var newRecipe = CurrentRecipe;
                         newRecipe.Header.Name = newName;
                         newRecipe.Header.CreateTime = DateTime.Now.ToString();
-                        var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", x, newName + ".rcp");
+                        var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", x,typeFolder, newName + ".rcp");
+                        FileInfo fi = new FileInfo(newrecipePath);
+                        var di = fi.Directory;
+                        if (!di.Exists)
+                        {
+                            di.Create();
+                        }
                         File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
                         UpdateRecipeFileList();
                     }
                 }
-                //moduleList.ForEach(x => 
-                //{
-                    
-                //});
             }
             else
             {
@@ -311,7 +284,13 @@ namespace Venus_MainPages.ViewModels
                     var newRecipe = CurrentRecipe;
                     newRecipe.Header.Name = newName;
                     newRecipe.Header.CreateTime = DateTime.Now.ToString();
-                    var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", moduleName, newName + ".rcp");
+                    var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", moduleName,typeFolder, newName + ".rcp");
+                    FileInfo fi = new FileInfo(newrecipePath);
+                    var di = fi.Directory;
+                    if (!di.Exists)
+                    { 
+                        di.Create();
+                    }
                     File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
                     UpdateRecipeFileList();
                 }
@@ -332,10 +311,6 @@ namespace Venus_MainPages.ViewModels
                 UpdateRecipeFileList();
                 treeViewRcpList.SelectedItemChanged += TreeViewRcpList_SelectedItemChanged;
 
-                //DispatcherTimer timer = new DispatcherTimer();
-                //timer.Interval = TimeSpan.FromSeconds(1);
-                //timer.Tick += Timer_Tick; ;
-                //timer.Start();
 
                 for (int i = 0; i < 5; i++)
                 {
@@ -386,8 +361,32 @@ namespace Venus_MainPages.ViewModels
                 return;
             try
             {
-                CurrentRecipeName = selectedItem.FileName;
-                string xmlRecipeData = m_uiRecipeManager.LoadRecipe(ModuleName, selectedItem.FileName);
+                string[] info = selectedItem.FileName.Split('\\');
+                //string path;
+                string xmlRecipeData = "";
+                if (info.Length == 1)
+                {
+                   
+                    CurrentRecipeName = info[0];
+                    typeFolder = "";
+                    string path = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName,$"{CurrentRecipeName}.rcp");
+                    xmlRecipeData = m_uiRecipeManager.LoadRecipeByPath(path);
+
+                }
+                else if (info.Length == 2)
+                {
+                    string type = info[0];
+                    typeFolder = type;
+                    CurrentRecipeName = info[1];
+                    string path = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, type, $"{CurrentRecipeName}.rcp");
+                    xmlRecipeData = m_uiRecipeManager.LoadRecipeByPath(path);
+
+                }
+                else
+                {
+                    return;
+                }
+               
                 if (xmlRecipeData == "")
                 {
                     treeViewRcpList.Items.Remove(selectedItem);
@@ -470,11 +469,11 @@ namespace Venus_MainPages.ViewModels
                     //string recipeContent = m_uiRecipeManager.GetRecipeTemplate(ModuleName);
 
                     //m_uiRecipeManager.SaveAsRecipe(ModuleName, recipeName, m_uiRecipeManager.LoadRecipe("system",folderName));
-                    if (SaveAsRecipe(recipeName, newRecipe))
+                    if (SaveAsRecipe2(recipeName, type.ToString(), newRecipe))
                     {
-                        //UpdateRecipeFileList();
+                        UpdateRecipeFileList();
                         //SelectRecipe(recipeName);
-                        treeViewRcpList.Items.Add(new TreeViewFileItem(dlg.InputText));
+                        //treeViewRcpList.Items.Add(new TreeViewFileItem(dlg.InputText));
                     }
                     else
                     {
@@ -495,13 +494,15 @@ namespace Venus_MainPages.ViewModels
             {
                 return;
             }
-            if (WPFMessageBox.ShowQuestion($"Delete {CurrentRecipeName}?","删除后无法恢复!!!") == MessageBoxResult.Yes)
+            if (WPFMessageBox.ShowQuestion($"Delete {typeFolder}Recipe {CurrentRecipeName}?","删除后无法恢复!!!") == MessageBoxResult.Yes)
             {
                 MenuItem mit = sender as MenuItem;
                 //string recipename = mit.Header.ToString();
-                m_uiRecipeManager.DeleteRecipe(ModuleName, CurrentRecipeName);
+                string path = typeFolder == "" ? CurrentRecipeName : $"{typeFolder}\\{CurrentRecipeName}";
+                m_uiRecipeManager.DeleteRecipe(ModuleName, path);
                 //PerformCreateRecipe(folderName);
-                treeViewRcpList.Items.Remove(selectedItem);
+                //treeViewRcpList.Items.Remove(selectedItem);
+                UpdateRecipeFileList();
             }
             
         }
@@ -517,7 +518,7 @@ namespace Venus_MainPages.ViewModels
                 var newRecipe = CurrentRecipe;
                 newRecipe.Header.Name = newName;
                 newRecipe.Header.CreateTime = DateTime.Now.ToString();
-                var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, newName + ".rcp");
+                var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName,typeFolder, newName + ".rcp");
                 File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
                 UpdateRecipeFileList();
             }               
@@ -528,18 +529,18 @@ namespace Venus_MainPages.ViewModels
             {
                 return;
             }
-            var newName= Interaction.InputBox(" ", "Rename Recipe", CurrentRecipeName, -1, -1);
-            if (newName != CurrentRecipeName && newName!="")
+            var newName = Interaction.InputBox(" ", "Rename Recipe", CurrentRecipeName, -1, -1);
+            if (newName != CurrentRecipeName && newName != "")
             {
-                var oldrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, CurrentRecipeName + ".rcp");
-                var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, newName + ".rcp");
-                CurrentRecipe.Header.Name = newName;
-                SaveRecipe(CurrentRecipeName, RecipeUnity.RecipeToString(CurrentRecipe));
-                File.Move(oldrecipePath, newrecipePath);
+                var newRecipe = CurrentRecipe;
+                newRecipe.Header.Name = newName;
+                newRecipe.Header.CreateTime = DateTime.Now.ToString();
+                var oldrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, typeFolder, CurrentRecipeName + ".rcp");
+                var newrecipePath = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName, typeFolder, newName + ".rcp");
+                File.Delete(oldrecipePath);
+                File.WriteAllText(newrecipePath, RecipeUnity.RecipeToString(newRecipe));
                 UpdateRecipeFileList();
             }
-            
-
         }
         public bool SaveAsRecipe(string recipeName, string recipeContent)
         {
@@ -559,22 +560,25 @@ namespace Venus_MainPages.ViewModels
             {
                 if (ele.Name == "File")
                 {
-                    string fileName = ele.Attributes["Name"].Value;
-                    fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
-                    TreeViewFileItem item = new TreeViewFileItem(ele.Attributes["Name"].Value);
-                    item.Tag = ele.Attributes["Name"].Value;
-                    //item.ToolTip = fileName;
-                    itemsControl.Items.Add(item);
+                    //string fileName = ele.Attributes["Name"].Value;
+                    //fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
+                    //TreeViewFileItem item = new TreeViewFileItem(ele.Attributes["Name"].Value);
+                    //item.Tag = ele.Attributes["Name"].Value;
+                    ////item.ToolTip = fileName;
+                    //itemsControl.Items.Add(item);
                 }
                 else if (ele.Name == "Folder")
                 {
                     string folderName = ele.Attributes["Name"].Value;
                     folderName = folderName.Substring(folderName.LastIndexOf('\\') + 1);
-                    TreeViewFolderItem item = new TreeViewFolderItem(folderName);
-                    item.Tag = ele.Attributes["Name"].Value;
-                    CreateTreeViewItems(ele, item);
-                    item.IsExpanded = false;
-                    itemsControl.Items.Add(item);
+                    if (folderName == Venus_Core.RecipeType.Process.ToString() || folderName == Venus_Core.RecipeType.Clean.ToString() || folderName == Venus_Core.RecipeType.Chuck.ToString() || folderName == Venus_Core.RecipeType.DeChuck.ToString())
+                    {
+                        TreeViewFolderItem item = new TreeViewFolderItem(folderName);
+                        item.Tag = ele.Attributes["Name"].Value;
+                        CreateTreeViewItems(ele, item);
+                        item.IsExpanded = false;
+                        itemsControl.Items.Add(item);
+                    }           
                 }
             }
         }
@@ -650,56 +654,60 @@ namespace Venus_MainPages.ViewModels
                         {
                             continue;
                         }
-                        string[] chucklist = new string[] { "" };
-                        ArrayList arrayList = new ArrayList(chucklist.ToList());
-                        IEnumerable<string> chlist= GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList().Where(item => item.ToLower().Contains("chuck") && (item.ToLower().Contains("dechuck") == false));
-                        foreach (var i in chlist)
-                        {
-                            arrayList.Add(i);
-                        }
-                        chucklist = (string[])arrayList.ToArray(typeof(string));
+                        //string[] chucklist = new string[] { "" };
+                        //ArrayList arrayList = new ArrayList(chucklist.ToList());
+                        //IEnumerable<string> chlist= GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList().Where(item => item.ToLower().Contains("chuck") && (item.ToLower().Contains("dechuck") == false));
+                        //foreach (var i in chlist)
+                        //{
+                        //    arrayList.Add(i);
+                        //}
+                        //chucklist = (string[])arrayList.ToArray(typeof(string));
                         StringBuilder stringBuilder = new StringBuilder();
                         //输出
-                        for (int i = 0; i < chucklist.Length; i++)
-                        {
-                            stringBuilder.Append(chucklist[i] + "\t");
-                        }
+                        //for (int i = 0; i < chucklist.Length; i++)
+                        //{
+                        //    stringBuilder.Append(chucklist[i] + "\t");
+                        //}
                         
                         control = new ComboBox()
                         {
-                            ItemsSource = chucklist
+                            ItemsSource = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\Chuck"))
+
                         };
                         control.Height = 23;
                         control.MinWidth = 100;
                         control.MaxWidth = 300;
                         control.SetBinding(ComboBox.SelectedItemProperty, binding);
+                        control.PreviewMouseLeftButtonDown += ChuckControl_PreviewMouseLeftButtonDown;
+                        
                         break;
                     case "DechuckRecipe":
                         if (currentChamber != JetChamber.Venus)
                         {
                             continue;
                         }
-                        string[] dechucklist = new string[] { "" };
-                        ArrayList dearrayList = new ArrayList(dechucklist.ToList());
-                        IEnumerable<string> delist = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList().Where(item => item.ToLower().Contains("dechuck"));
-                        foreach (var i in delist)
-                        {
-                            dearrayList.Add(i);
-                        }
-                        dechucklist = (string[])dearrayList.ToArray(typeof(string));
-                        StringBuilder destringBuilder = new StringBuilder();
-                        for (int i = 0; i < dechucklist.Length; i++)
-                        {
-                            destringBuilder.Append(dechucklist[i] + "\t");
-                        }
+                        //string[] dechucklist = new string[] { "" };
+                        //ArrayList dearrayList = new ArrayList(dechucklist.ToList());
+                        //IEnumerable<string> delist = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", ModuleName)).ToList().Where(item => item.ToLower().Contains("dechuck"));
+                        //foreach (var i in delist)
+                        //{
+                        //    dearrayList.Add(i);
+                        //}
+                        //dechucklist = (string[])dearrayList.ToArray(typeof(string));
+                        //StringBuilder destringBuilder = new StringBuilder();
+                        //for (int i = 0; i < dechucklist.Length; i++)
+                        //{
+                        //    destringBuilder.Append(dechucklist[i] + "\t");
+                        //}
                         control = new ComboBox()
                         {
-                            ItemsSource= dechucklist
+                            ItemsSource = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\DeChuck"))
                         };
                         control.Height = 23;
                         control.MinWidth = 100;
                         control.MaxWidth = 300;
                         control.SetBinding(ComboBox.SelectedItemProperty, binding);
+                        control.PreviewMouseLeftButtonDown += DechuckControl_PreviewMouseLeftButtonDown;
 
                         break;
 
@@ -758,6 +766,16 @@ namespace Venus_MainPages.ViewModels
                 HeadWrapPanel.Children.Add(control);
             }
         }
+
+        private void ChuckControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            (sender as ComboBox).ItemsSource = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\Chuck"));
+        }
+        private void DechuckControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            (sender as ComboBox).ItemsSource = GetFilesNames(Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", $"{ModuleName}\\DeChuck"));
+        }
+
         private void ChangeUI(object sender, SelectionChangedEventArgs e)
         {
             var t = sender as ComboBox;
@@ -1408,6 +1426,7 @@ namespace Venus_MainPages.ViewModels
             doc.LoadXml(GetXmlRecipeList());
             treeViewRcpList.Items.Clear();
             CreateTreeViewItems(doc.DocumentElement, this.treeViewRcpList);
+            ExpandAllItems(this.treeViewRcpList);
         }
         private void LoadRecipe(Recipe recipe)
         {
@@ -1426,9 +1445,13 @@ namespace Venus_MainPages.ViewModels
                 Grid chuckGrid = new Grid();
                 chuckGrid.IsEnabled = false;
                 chuckGrid.Margin = new Thickness(15);
-                string chuckRecipeData = m_uiRecipeManager.LoadRecipe(ModuleName, CurrentRecipe.Header.ChuckRecipe);
-                //index = 0;
+                string chuckRecipeData = m_uiRecipeManager.LoadRecipe(ModuleName, $"Chuck\\{CurrentRecipe.Header.ChuckRecipe}");
+                if (chuckRecipeData == "")
+                {
+                    return;
+                }
                 var chuckRecipe = Recipe.Load(chuckRecipeData);
+                
                 for (int i = 0; i < chuckRecipe.Steps.Count; i++)
                 {
                     RecipeStepToGridColumn(chuckRecipe.Steps[i], chuckGrid, i, false);
@@ -1453,7 +1476,7 @@ namespace Venus_MainPages.ViewModels
                 Grid deChuckGrid = new Grid();
                 deChuckGrid.IsEnabled = false;
                 deChuckGrid.Margin = new Thickness(15);
-                string DechuckRecipeData = m_uiRecipeManager.LoadRecipe(ModuleName, CurrentRecipe.Header.DechuckRecipe);
+                string DechuckRecipeData = m_uiRecipeManager.LoadRecipe(ModuleName, $"DeChuck\\{CurrentRecipe.Header.DechuckRecipe}");
                 //index = 0;
                 var dechuckRecipe = Recipe.Load(DechuckRecipeData);
                 for (int i = 0; i < dechuckRecipe.Steps.Count; i++)
@@ -1546,6 +1569,27 @@ namespace Venus_MainPages.ViewModels
             kepler2300Tolerances.Add(new Kepler2300Tolerance());
             var str= SerializeHelper.Instance.ObjectToJsonString<List<Kepler2300Tolerance>>(kepler2300Tolerances);
         }
+        private  void ExpandAllItems(ItemsControl control)
+        {
+            if (control == null)
+            {
+                return;
+            }
+
+            foreach (Object item in control.Items)
+            {
+                System.Windows.Controls.TreeViewItem treeItem = control.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
+
+
+                if (treeItem == null || !treeItem.HasItems)
+                {
+                    continue;
+                }
+
+                treeItem.IsExpanded = true;
+                ExpandAllItems(treeItem as ItemsControl);
+            }
+        }
         #endregion
     }
 }

+ 9 - 2
Venus/Venus_MainPages/ViewModels/SequenceViewModel.cs

@@ -477,8 +477,15 @@ namespace Venus_MainPages.ViewModels
                     break;
                 }
             }
-
-            List<string> lstFiles = provider.GetRecipesByPath($"{param.PrefixPath}");//m_uiSequenceManager.GetRecipesByPath($"{param.PrefixPath}");
+            List<string> lstFiles=new List<string>();
+            if (param.Name.Contains("Clean"))
+            {
+                lstFiles = provider.GetRecipesByPath($"{param.PrefixPath}").Where(x => x.Split('\\')[1] == "Clean").ToList();//m_uiSequenceManager.GetRecipesByPath($"{param.PrefixPath}");
+            }
+            else
+            { 
+                lstFiles = provider.GetRecipesByPath($"{param.PrefixPath}").Where(x => x.Split('\\')[1] == "Process").ToList();//m_uiSequenceManager.GetRecipesByPath($"{param.PrefixPath}");
+            }
 
             dataContext.Files = new ObservableCollection<FileNode>(RecipeSequenceTreeBuilder.GetFiles("", lstFiles));
 

+ 17 - 3
Venus/Venus_RT/Devices/EFEM/JetEfem.cs

@@ -16,6 +16,7 @@ using Aitex.Core.RT.Log;
 using Aitex.Core.Util;
 using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
 using Venus_RT.Devices.YASKAWA;
+using System.Collections.Concurrent;
 
 namespace Venus_RT.Devices.EFEM
 {
@@ -54,6 +55,7 @@ namespace Venus_RT.Devices.EFEM
         public override bool LiftIsUp { get { return _LiftIsUp; } }
         public override bool LiftIsDown { get { return _LiftIsDown; } }
 
+        private BlockingCollection<RobotAnimationData> blockingCollection = new BlockingCollection<RobotAnimationData>();
 
 
         public JetEfem()
@@ -93,6 +95,16 @@ namespace Venus_RT.Devices.EFEM
             _subscribeLoc(ModuleName.LP1, SC.GetValue<int>("EFEM.LoadPort.SlotNumber"));
             _subscribeLoc(ModuleName.LP2, SC.GetValue<int>("EFEM.LoadPort.SlotNumber"));
             _subscribeLoc(ModuleName.LP3, SC.GetValue<int>("EFEM.LoadPort.SlotNumber"));
+            Task.Run(() =>
+            {
+                foreach (var data in blockingCollection.GetConsumingEnumerable())
+                {
+                    _robotMoveInfo.Action = data.Action;
+                    _robotMoveInfo.ArmTarget = data.Hand == Hand.Blade1 ? RobotArm.ArmA : (data.Hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
+                    _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{data.Target}";
+                    System.Threading.Thread.Sleep(300);
+                }
+            });
 
         }
 
@@ -659,9 +671,11 @@ namespace Venus_RT.Devices.EFEM
         }
         public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target)
         {
-            _robotMoveInfo.Action = action;
-            _robotMoveInfo.ArmTarget = hand == Hand.Blade1 ? RobotArm.ArmA : (hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
-            _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{target}";
+            //_robotMoveInfo.Action = action;
+            //_robotMoveInfo.ArmTarget = hand == Hand.Blade1 ? RobotArm.ArmA : (hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
+            //_robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{target}";
+            blockingCollection.Add(new RobotAnimationData(action, hand, target));
+
         }
 
         private void OnReceiveMessage(string RevMsg)

+ 19 - 3
Venus/Venus_RT/Devices/TM/SIASUNRobot.cs

@@ -12,6 +12,8 @@ using Aitex.Core.RT.Log;
 using System.Text.RegularExpressions;
 using MECF.Framework.Common.CommonData;
 using System.Threading;
+using System.Collections.Concurrent;
+using System.Threading.Tasks;
 
 namespace Venus_RT.Devices
 {
@@ -64,6 +66,7 @@ namespace Venus_RT.Devices
 
         private const string EOF = "\r\n";
 
+        private BlockingCollection<RobotAnimationData> blockingCollection = new BlockingCollection<RobotAnimationData>();
         public SIASUNRobot()
         {
             _socket = new AsyncSocket("", EOF);
@@ -85,6 +88,17 @@ namespace Venus_RT.Devices
             _StationNumbers[ModuleName.PMF] = SC.GetValue<int>("TM.PMFStationNumber");
 
             _checkLoadStation = SC.GetValue<int>("TM.CheckLoadStation");
+
+            Task.Run(() =>
+            {
+                foreach (var data in blockingCollection.GetConsumingEnumerable())
+                {
+                    _robotMoveInfo.Action = data.Action;
+                    _robotMoveInfo.ArmTarget = data.Hand == Hand.Blade1 ? RobotArm.ArmA : (data.Hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
+                    _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{data.Target}";
+                    System.Threading.Thread.Sleep(300);
+                }
+            });
         }
         public bool Home()
         {
@@ -646,9 +660,10 @@ namespace Venus_RT.Devices
 
         public void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target)
         {
-            _robotMoveInfo.Action = action;
-            _robotMoveInfo.ArmTarget = hand == Hand.Blade1 ? RobotArm.ArmA : (hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
-            _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{target}";
+            //_robotMoveInfo.Action = action;
+            //_robotMoveInfo.ArmTarget = hand == Hand.Blade1 ? RobotArm.ArmA : (hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
+            //_robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{target}";
+            blockingCollection.Add(new RobotAnimationData(action,hand,target));
         }
 
         private void GetEventMsg(string revMsg)
@@ -738,4 +753,5 @@ namespace Venus_RT.Devices
             }
         }
     }
+    
 }

+ 1 - 1
Venus/Venus_RT/Modules/AutoCycle.cs

@@ -1834,7 +1834,7 @@ namespace Venus_RT.Modules
                             if (!string.IsNullOrEmpty(recipeName))
                             {
                                 var recipeContent =
-                                    RecipeFileManager.Instance.LoadRecipe($"{module}", recipeName, false);
+                                    RecipeFileManager.Instance.LoadRecipe($"{module}", recipeName, false,"Process");
                                 if (string.IsNullOrEmpty(recipeContent))
                                 {
                                     reason = $"Can not find recipe file{recipeName}";

+ 4 - 4
Venus/Venus_RT/Modules/PMs/PMProcessRoutine.cs

@@ -165,7 +165,7 @@ namespace Venus_RT.Modules.PMs
             currentRecipeResult = new RecipeResult();
             currentRecipeResult.RecipeName = recipeName;
 
-            string recipeContent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipeName, false);
+            string recipeContent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipeName, false,RecipeType.Process.ToString());
             Recipe recipe = Recipe.Load(recipeContent);
             currentRecipeResult.RecipeStepCount = recipe.Steps.Count;
             if (recipe == null)
@@ -182,7 +182,7 @@ namespace Venus_RT.Modules.PMs
                 case RecipeType.Process:
                     if (_recipeRunningMode == 1 && recipe.Header.ChuckRecipe != null && !string.IsNullOrEmpty(recipe.Header.ChuckRecipe))
                     {
-                        string chuckcontent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipe.Header.ChuckRecipe, false);
+                        string chuckcontent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipe.Header.ChuckRecipe, false, RecipeType.Chuck.ToString());
                         var chuckRecipe = Recipe.Load(chuckcontent);
                         if (chuckRecipe != null)
                         {
@@ -199,7 +199,7 @@ namespace Venus_RT.Modules.PMs
                     if (_recipeRunningMode == 1 && recipe.Header.DechuckRecipe != null && !string.IsNullOrEmpty(recipe.Header.DechuckRecipe))
                     {
 
-                        string dechuckcontent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipe.Header.DechuckRecipe, false);
+                        string dechuckcontent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipe.Header.DechuckRecipe, false, RecipeType.DeChuck.ToString());
                         var dechuckRecipe = Recipe.Load(dechuckcontent);
                         if (dechuckRecipe != null)
                         {
@@ -464,7 +464,7 @@ namespace Venus_RT.Modules.PMs
         {
             _currentRecipe.Steps[_currentStep].End();
 
-            RecipeFileManager.Instance.SaveAsRecipe(Module.ToString(), CurrentRunningRecipe, RecipeUnity.RecipeToString(_currentRecipe));
+            //RecipeFileManager.Instance.SaveAsRecipe(Module.ToString(), CurrentRunningRecipe, RecipeUnity.RecipeToString(_currentRecipe));
             _stepTime.Stop();
             WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Idle);
             CloseAllValves();

+ 0 - 1
Venus/Venus_Simulator/Devices/TMSimulatorServer.cs

@@ -36,7 +36,6 @@ namespace Venus_Simulator.Devices
 
             if (str.Contains("RQ WAF_CEN DATA"))
             {
-                Thread.Sleep(1500);
 
                 string t = new Random().Next(0, 359).ToString().PadLeft(6, '0');
                 string r = new Random().Next(0, 50000).ToString().PadLeft(6, '0');

+ 1 - 1
Venus/Venus_Themes/UserControls/Loadport.xaml

@@ -5,7 +5,7 @@
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:Venus_Themes.UserControls"
              mc:Ignorable="d" 
-             d:DesignHeight="450" d:DesignWidth="800">
+             d:DesignHeight="450" d:DesignWidth="800" Background="#B1D2F2" Opacity="0.9">
     <Viewbox Stretch="Uniform" Width="300" Height="300">
         <Canvas UseLayoutRounding="False"  LayoutTransform="Identity" Width="109.461" Height="112.5" HorizontalAlignment="Left" VerticalAlignment="Top">
             <Canvas  Width="109.459" Height="104.054" Canvas.Left="0.001" Canvas.Top="7.946">

+ 3 - 3
Venus/Venus_Themes/UserControls/RecipeNameInputDlg.xaml

@@ -4,19 +4,19 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:Venus_Themes.UserControls"
-            Title="新建配方"
+            Title="New Recipe"
         WindowStartupLocation="CenterOwner"
         WindowStyle="SingleBorderWindow" ResizeMode="NoResize" ShowInTaskbar="False"
         Background="LightSkyBlue" SizeToContent="WidthAndHeight">
     <StackPanel>
-        <TextBlock Text="请选择配方类型:" HorizontalAlignment="Left" FontSize="12" Margin="15" />
+        <TextBlock Text="Select Recipe Type:" HorizontalAlignment="Left" FontSize="12" Margin="15" />
         <StackPanel Orientation="Horizontal" Margin="5,0,0,0">
             <RadioButton Content="Chuck"      Margin="5,0,0,0" Checked="RadioButton_Checked" x:Name="chuckRadioButton"/>
             <RadioButton Content="DeChuck"    Margin="5,0,0,0" Checked="RadioButton_Checked" x:Name="dechuckRadioButton"/>
             <RadioButton Content="Process"    Margin="5,0,0,0" Checked="RadioButton_Checked" IsChecked="True"/>
             <RadioButton Content="Clean"      Margin="5,0,0,0" Checked="RadioButton_Checked"/>
         </StackPanel>
-        <TextBlock Text="请输入配方名称:" HorizontalAlignment="Left" FontSize="12" Margin="15" x:Name="labelCaption"/>
+        <TextBlock Text="Input Recipe Name:" HorizontalAlignment="Left" FontSize="12" Margin="15" x:Name="labelCaption"/>
         <TextBox x:Name="textBoxInput" FontSize="12"  TextChanged="textBoxInput_TextChanged"  Width="150" HorizontalAlignment="Left" Margin="15,0,150,0" BorderThickness="0,0,0,1" Background="Transparent"/>
 
         <StackPanel Orientation="Horizontal"  Margin="10">