0
点赞
收藏
分享

微信扫一扫

WPF学习总结

小桥流水2016 2022-04-14 阅读 48

1接口

    /// <summary>
    /// Interface description of the interaction between the <see cref="ProcessRecipeScreen"/> the ViewModel.
    /// </summary>
    public interface IProcessRecipeScreenViewModel : IWpfBaseControlViewModel
    {
        /// <summary>
        /// EPD Config List
        /// </summary>
        ObservableCollection<string> EPDConfigList { get; set; }
        /// <summary>
        /// Button  is enable.
        /// </summary>
        bool ButtonIsView { get; }

        /// <summary>
        /// the Create Button Enable
        /// </summary>
        bool CreateEnable { get; set; }

        /// <summary>
        /// the Edit Button Enable
        /// </summary>
        bool EditEnable { get; set; }

        /// <summary>
        /// the EPDConfig Combox Enable
        /// </summary>
        bool EPDConfigEnable { get; set; }

        /// <summary>
        /// the Delete Button Enable
        /// </summary>
        bool DeleteEnable { get; set; }

        /// <summary>
        /// the Cancel Button Enable
        /// </summary>
        bool CancelEnable { get; set; }

        /// <summary>
        /// the AddStep Button Enable
        /// </summary>
        bool AddStepEnable { get; set; }

        /// <summary>
        /// the Remove  Step Button Enable
        /// </summary>
        bool RemoveStepEnable { get; set; }

        /// <summary>
        /// the Copy   Step Button Enable
        /// </summary>
        bool CopyStepEnable { get; set; }

        /// <summary>
        /// the Paste   Step Button Enable
        /// </summary>
        bool PasteStepEnable { get; set; }

        /// <summary>
        /// the Move  Step Button Enable
        /// </summary>
        bool MoveStepEnable { get; set; }

        /// <summary>
        /// the Save   Button Enable
        /// </summary>
        bool SaveEnable { get; set; }

        /// <summary>
        /// the Saveas   Button Enable
        /// </summary>
        bool SaveAsEnable { get; set; }


        /// <summary>
        /// the Show OES Param   Button Enable
        /// </summary>
        bool ShowOESParamEnable { get; set; }

        /// <summary>
        /// the Restore Button Enable
        /// </summary>
        bool RestoreEnable { get; set; }

        /// <summary>
        /// Process RecipeIs Editing.
        /// </summary>
        bool ProcessRecipeIsEditing { get; set; }

        /// <summary>
        /// Create process user
        /// </summary>
        string CreatedBy { get; set; }

        /// <summary>
        /// Create process time
        /// </summary>
        string CreateTime { get; set; }
        /// <summary>
        /// Modify process time
        /// </summary>
        string ModifyTime { get; set; }

        /// <summary>
        /// Comments of process
        /// </summary>
        string Comments { get; set; }

        /// <summary>
        /// create recipe process
        /// </summary>
        public event Action CreateRecipeAction;

        /// <summary>
        /// create recipe process
        /// </summary>
        public event Action ShowOESParamAction;

        /// <summary>
        /// Recipe statuses.
        /// </summary>
        IRecipeTreeViewViewModel RecipeTreeViewViewModel { get; }

        /// <summary>
        /// used to bindging datagrid table
        /// </summary>
        ObservableCollection<ExpandoObject> ProcessRecipeViewModel { get; set; }

        /// <summary>
        /// used to bindging datagrid table
        /// </summary>
        List<ColumeModel> ColumeModels { get; }
        /// <summary>
        /// Cureent PM Number
        /// </summary>
        string PMNumber { get; set; }

        /// <summary>
        /// Curent Recipe Location
        /// </summary>
        string RecipeLocation { get; set; }
        /// <summary>
        /// Command to create recipe.
        /// </summary>
        ICommand CreateCommand { get; }

        /// <summary>
        /// Recipe Name.
        /// </summary>
        string DummyRecipeName { get; set; }

        /// <summary>
        /// the status of recipe
        /// </summary>
        bool isRecipeOpened { get; set; }

        /// <summary>
        /// Dummy Process Recipe.
        /// </summary>
        ProcessRecipe DummyProcessRecipe { get; set; }

        /// <summary>
        /// crueent id of process recipe.
        /// </summary>
        long DummyProcessLockId { get; set; }

        /// <summary>
        /// Create Process Name
        /// </summary>
        string createProcessName { get; set; }
        /// <summary>
        /// used to edit process
        /// </summary>
        string RecipeToSend { get; set; }
        /// <summary>
        /// Command to Add Step to recipe.
        /// </summary>
        ICommand AddStepCommand { get; }

        /// <summary>
        /// add step process
        /// </summary>
        event Action AddStepAction;

        /// <summary>
        /// Remove step process
        /// </summary>
        event Action RemoveStepAction;
        /// <summary>
        /// Command to Remove Step to recipe.
        /// </summary>
        ICommand RemoveStepCommand { get; }

        /// <summary>
        /// Copy step process
        /// </summary>
        event Action CopyStepAction;

        /// <summary>
        /// Command to Copy Step to recipe.
        /// </summary>
        ICommand CopyCommand { get; }

        /// <summary>
        /// Paste step process
        /// </summary>
        event Action PasteStepAction;
        /// <summary>
        /// Command to Paste Step to recipe.
        /// </summary>
        ICommand PasteCommand { get; }

        /// <summary>
        /// Paste step process
        /// </summary>
        event Action MoveStepAction;
        /// <summary>
        /// Command to Paste Step to recipe.
        /// </summary>
        ICommand MoveStepCommand { get; }

        /// <summary>
        /// Save process
        /// </summary>
        event Action SaveProcessAction;
        /// <summary>
        /// Command to Save Process.
        /// </summary>
        ICommand SaveProcessCommand { get; }

        /// <summary>
        /// Save process
        /// </summary>
        event Action SaveAsProcessAction;
        /// <summary>
        /// Command to Save Process.
        /// </summary>
        ICommand SaveAsProcessCommand { get; }


        /// <summary>
        /// Edit process
        /// </summary>
        event Action EditProcessAction;
        /// <summary>
        /// Command to Edit Process.
        /// </summary>
        ICommand EditProcessCommand { get; }

        /// <summary>
        /// Delete process
        /// </summary>
        event Action DeleteProcessAction;
        /// <summary>
        /// Command to Delete Process.
        /// </summary>
        ICommand DeleteProcessCommand { get; }

        /// <summary>
        /// Cancel all process
        /// </summary>
        event Action CancelAllProcessAction;

        /// <summary>
        /// Cancel process
        /// </summary>
        event Action CancelProcessAction;
        /// <summary>
        /// Command to Cancel Process.
        /// </summary>
        ICommand CancelProcessCommand { get; }

        /// <summary>
        /// Cancel process
        /// </summary>
        event Action RestoreProcessAction;
        /// <summary>
        /// Command to Cancel Process.
        /// </summary>
        ICommand RestoreProcessCommand { get; }

        /// <summary>
        /// Command to Cancel Process.
        /// </summary>
        ICommand ShowOESParamCommand { get; }
    }

    /// <summary>
    /// 
    /// </summary>
    public class ColumeModel
    {
        /// <summary>
        /// datagrid Colume Name
        /// </summary>
        public string ColumeName { get; set; }

        /// <summary>
        ///  datagrid Colume Type
        /// </summary>
        public ControlDataType ColueType { set; get; }

        /// <summary>
        /// datagrid  recipe Parameter
        /// </summary>
        public RecipeParameter recipeParameter { set; get; }

        /// <summary>
        /// ColumeName_SoftTolerance_1
        /// </summary>
        public ColumeModel SoftTolerance { set; get; }

        /// <summary>
        /// ColumeName_HardTolerance_1
        /// </summary>
        public ColumeModel HardTolerance { set; get; }
    }
    /// <summary>
    /// 
    /// </summary>
    public enum ControlDataType
    {
        /// <summary>
        /// grid cell is type  Label.
        /// </summary>
        Label,
        /// <summary>
        /// grid cell is type  TextBlocak.
        /// </summary>
        TextBlocak,
        /// <summary>
        /// grid cell is type  CheckBox.
        /// </summary>
        CheckBox,
        /// <summary>
        /// grid cell is type  Combox.
        /// </summary>
        Combox,
        /// <summary>
        /// grid cell is type  TextBox.
        /// </summary>
        TextBox
    }

2接口实现

/// <summary>
    /// ViewModel for the <see cref="ProcessRecipeScreen"/> View.
    /// </summary>
    public class ProcessRecipeScreenViewModel : WpfBaseControlViewModel, IProcessRecipeScreenViewModel
    {
        #region Fields
        private string recipeToSend;
        private bool epdConfigEnable;
        private bool buttonIsView;
        private bool createEnable;
        private bool editEnable;
        private bool deleteEnable;
        private bool cancelEnable;
        private bool addStepEnable;
        private bool removeStepEnable;
        private bool copyStepEnable;
        private bool pasteStepEnable;
        private bool moveStepEnable;
        private bool saveEnable;
        private bool saveAsEnable;
        private bool showOESParamEnable;
        private bool restoreEnable;
        private long dummyProcessLockId;
        private bool processRecipeIsEditing;
        private ProcessRecipe dummyProcessRecipe;
        private string pmnumber;
        private string createdBy;
        private string createTime;
        private string modifyTime;
        private string comments;
        private readonly DelegateCommand sendCommand;
        private readonly DelegateCommand queryRecipeCommand;
        private readonly DelegateCommand createCommand;
        private readonly DelegateCommand moveStepCommand;
        private readonly DelegateCommand addStepCommand;
        private readonly DelegateCommand removeStepCommand;
        private readonly DelegateCommand copyCommand;
        private readonly DelegateCommand pasteCommand;
        private readonly DelegateCommand editProcessCommand;
        private readonly DelegateCommand deleteProcessCommand;
        private readonly DelegateCommand cancelProcessCommand;
        private readonly DelegateCommand saveProcessCommand;
        private readonly DelegateCommand saveAsProcessCommand;
        private readonly DelegateCommand restoreProcessCommand;
        private readonly DelegateCommand showOESParamCommand; 
        private string searchRecipe;
        private string recipeLocation;
        private string RecipeFullFolderName = "";
        private string CreateProcessName;
        private string dummyRecipeName;
        private RecipeTemplate ProcessRecipeTemplate;
        private bool IsRecipeOpened;
        private bool IsRecipeDeleted = true;
        private ObservableCollection<ExpandoObject> processRecipeViewModel = new ObservableCollection<ExpandoObject>();
        private ObservableCollection<string> epdConfigList = new ObservableCollection<string>();
        private List<ColumeModel> columeModels = new List<ColumeModel>();
        private ObservableCollection<string> allfolder = new ObservableCollection<string>();
        #endregion

        #region Constructors
        /// <summary>
        /// Construct a new instance of the ViewModel.
        /// </summary>
        /// <param name="caption">String label for this ViewModel.</param>
        public ProcessRecipeScreenViewModel(string caption)
        {
            ColumeModels = new List<ColumeModel>();
            Allfolder = new ObservableCollection<string>();
            Caption = caption;
            sendCommand = new DelegateCommand { CommandAction = PerformSend };
            queryRecipeCommand = new DelegateCommand { CommandAction = RecipeFilter };
            createCommand = new DelegateCommand { CommandAction = CreateRecipeProcess };
            addStepCommand = new DelegateCommand { CommandAction = AddProcessRecipeStep };
            removeStepCommand = new DelegateCommand { CommandAction = RemoveProcessRecipeStep };
            moveStepCommand = new DelegateCommand { CommandAction = MoveProcessRecipeStep };
            copyCommand = new DelegateCommand { CommandAction = CopyProcessRecipeStep };
            pasteCommand = new DelegateCommand { CommandAction = PasteProcessRecipeStep };
            saveProcessCommand = new DelegateCommand { CommandAction = SaveProcess };
            saveAsProcessCommand = new DelegateCommand { CommandAction = SaveAsProcess };
            restoreProcessCommand = new DelegateCommand { CommandAction = RestoreProcessRecipeStep };
            editProcessCommand = new DelegateCommand { CommandAction = EditProcess };
            deleteProcessCommand = new DelegateCommand { CommandAction = DeleteProcess };
            cancelProcessCommand = new DelegateCommand { CommandAction = ConcelProcess };
            showOESParamCommand = new DelegateCommand { CommandAction = ShowOESParamCommandProcess };
            PolicyManager.AddActions(new PolicyAction(isEnabled =>
            {
                ButtonIsView = isEnabled;
            },
            new UI.Common.Framework.Policies.DisablePolicy(DisablePolicyType.GuiInViewMode)));
            PMNumber = "";
            AddScreenPrivilege("Process Recipe", "Process Recipe screen for the Operations related screens.");
        }
        #endregion

        #region Properties

        /// <summary>
        /// Command for sending a recipe.
        /// </summary>
        public ICommand SendCommand
        {
            get { return sendCommand; }
        }

        /// <summary>
        /// Get and set the name of the selected recipe to send.
        /// </summary>
        /// <remarks>Setting this property will generate the <see cref="BaseNotifyPropertyChanged.PropertyChanged"/> event.</remarks>
        public string RecipeToSend
        {
            get { return recipeToSend; }
            set
            {
                Set(() => RecipeToSend, ref recipeToSend, value);
                UpdateCommandStatus();
            }
        }

        /// <summary>
        /// Event fired when Materials collection is changed.
        /// </summary>
        public event Action MaterialsChanged = delegate { };
        /// <summary>
        /// Event fired when Materials collection is changed.
        /// </summary>
        public event Action CreateRecipeAction = delegate { };

        /// <summary>
        /// Event fired when Materials collection is changed.
        /// </summary>
        public event Action ShowOESParamAction = delegate { };
        
        /// <summary>
        /// Command to send the message.
        /// </summary>
        public ICommand CreateCommand
        {
            get { return createCommand; }
        }
        /// <summary>
        ///  add step process
        /// </summary>
        public event Action MoveStepAction = delegate { };
        /// <summary>
        ///  add step process
        /// </summary>
        public event Action AddStepAction = delegate { };
        /// <summary>
        ///  remove step process
        /// </summary>
        public event Action RemoveStepAction = delegate { };
        /// <summary>
        ///  copy step process
        /// </summary>
        public event Action CopyStepAction = delegate { };
        /// <summary>
        ///  Paste step process
        /// </summary>
        public event Action PasteStepAction = delegate { };

        /// <summary>
        ///  Paste step process
        /// </summary>
        public event Action SaveProcessAction = delegate { };
        /// <summary>
        ///  Paste step process
        /// </summary>
        public event Action SaveAsProcessAction = delegate { };

        /// <summary>
        ///   Edit step process
        /// </summary>
        public event Action EditProcessAction = delegate { };

        /// <summary>
        ///   Edit step process
        /// </summary>
        public event Action DeleteProcessAction = delegate { };

        /// <summary>
        ///   Edit step process
        /// </summary>
        public event Action CancelProcessAction = delegate { };

        /// <summary>
        ///   Edit step process
        /// </summary>
        public event Action CancelAllProcessAction = delegate { };

        /// <summary>
        ///   Restore step process
        /// </summary>
        public event Action RestoreProcessAction = delegate { };
        /// <summary>
        ///  Command to Add Step to recipe
        /// </summary>
        public ICommand SaveProcessCommand
        {
            get { return saveProcessCommand; }
        }
        /// <summary>
        ///  Command to Add Step to recipe
        /// </summary>
        public ICommand RestoreProcessCommand
        {
            get { return restoreProcessCommand; }
        }

        /// <summary>
        ///  Command to Show OES Param to recipe
        /// </summary>
        public ICommand ShowOESParamCommand
        {
            get { return showOESParamCommand; }
        }

        /// <summary>
        ///  Command to Add Step to recipe
        /// </summary>
        public ICommand SaveAsProcessCommand
        {
            get { return saveAsProcessCommand; }
        }
        /// <summary>
        ///  Command to Add Step to recipe
        /// </summary>
        public ICommand AddStepCommand
        {
            get { return addStepCommand; }
        }
        /// <summary>
        ///  Command to Remove Step to recipe
        /// </summary>
        public ICommand RemoveStepCommand
        {
            get { return removeStepCommand; }
        }

        /// <summary>
        ///  Command to Remove Step to recipe
        /// </summary>
        public ICommand MoveStepCommand
        {
            get { return moveStepCommand; }
        }
        /// <summary>
        ///  Command to copy Step to recipe
        /// </summary>
        public ICommand CopyCommand
        {
            get { return copyCommand; }
        }
        /// <summary>
        ///  Command to paste Step to recipe
        /// </summary>
        public ICommand PasteCommand
        {
            get { return pasteCommand; }
        }

        /// <summary>
        ///  Command to Edit process
        /// </summary>
        public ICommand EditProcessCommand
        {
            get { return editProcessCommand; }
        }

        /// <summary>
        ///  Command to Delete process
        /// </summary>
        public ICommand DeleteProcessCommand
        {
            get { return deleteProcessCommand; }
        }

        /// <summary>
        ///  Command to Cancel process
        /// </summary>
        public ICommand CancelProcessCommand
        {
            get { return cancelProcessCommand; }
        }
        /// <summary>
        /// The ID of the current job associated with the load port.
        /// </summary>
        /// <remarks>Setting this property will generate a <see cref="BaseNotifyPropertyChanged.PropertyChanged"/> event.</remarks>
        public string PMNumber
        {
            get { return pmnumber; }
            set
            {
                Set(() => PMNumber, ref pmnumber, value);
            }
        }


        /// <summary>
        /// Restore  button is Enable.
        /// </summary>
        public bool RestoreEnable
        {
            get { return restoreEnable; }
            set
            {
                Set(() => RestoreEnable, ref restoreEnable, value);
            }
        }

        /// <summary>
        /// showOESParam  button is Enable.
        /// </summary>
        public bool ShowOESParamEnable
        {
            get { return showOESParamEnable; }
            set
            {
                Set(() => ShowOESParamEnable, ref showOESParamEnable, value);
            }
        }

        /// <summary>
        /// Save as  button is Enable.
        /// </summary>
        public bool SaveAsEnable
        {
            get { return saveAsEnable; }
            set
            {
                Set(() => SaveAsEnable, ref saveAsEnable, value);
            }
        }

        /// <summary>
        /// save button is Enable.
        /// </summary>
        public bool SaveEnable
        {
            get { return saveEnable; }
            set
            {
                Set(() => SaveEnable, ref saveEnable, value);
            }
        }

        /// <summary>
        /// Process Recipe Is Editing.
        /// </summary>
        public bool ProcessRecipeIsEditing
        {
            get { return processRecipeIsEditing; }
            set
            {
                Set(() => ProcessRecipeIsEditing, ref processRecipeIsEditing, value);
            }
        }

        /// <summary>
        /// Move  button is Enable.
        /// </summary>
        public bool MoveStepEnable
        {
            get { return moveStepEnable; }
            set
            {
                Set(() => MoveStepEnable, ref moveStepEnable, value);
            }
        }

        /// <summary>
        /// remove  button is Enable.
        /// </summary>
        public bool PasteStepEnable
        {
            get { return pasteStepEnable; }
            set
            {
                Set(() => PasteStepEnable, ref pasteStepEnable, value);
            }
        }

        /// <summary>
        /// remove  button is Enable.
        /// </summary>
        public bool CopyStepEnable
        {
            get { return copyStepEnable; }
            set
            {
                Set(() => CopyStepEnable, ref copyStepEnable, value);
            }
        }

        /// <summary>
        /// remove  button is Enable.
        /// </summary>
        public bool RemoveStepEnable
        {
            get { return removeStepEnable; }
            set
            {
                Set(() => RemoveStepEnable, ref removeStepEnable, value);
            }
        }

        /// <summary>
        /// Add button is Enable.
        /// </summary>
        public bool AddStepEnable
        {
            get { return addStepEnable; }
            set
            {
                Set(() => AddStepEnable, ref addStepEnable, value);
            }
        }

        /// <summary>
        /// cancel button is Enable.
        /// </summary>
        public bool CancelEnable
        {
            get { return cancelEnable; }
            set
            {
                Set(() => CancelEnable, ref cancelEnable, value);
            }
        }

        /// <summary>
        /// edit button is Enable.
        /// </summary>
        public bool DeleteEnable
        {
            get { return deleteEnable; }
            set
            {
                Set(() => DeleteEnable, ref deleteEnable, value);
            }
        }

        /// <summary>
        /// edit button is Enable.
        /// </summary>
        public bool EditEnable
        {
            get { return editEnable; }
            set
            {
                Set(() => EditEnable, ref editEnable, value);
            }
        }

        /// <summary>
        /// Create button is Enable.
        /// </summary>
        public bool CreateEnable
        {
            get { return createEnable; }
            set
            {
                Set(() => CreateEnable, ref createEnable, value);
            }
        }

        /// <summary>
        /// is Recipe Opened?.
        /// </summary>
        public bool isRecipeOpened
        {
            get { return IsRecipeOpened; }
            set
            {
                Set(() => isRecipeOpened, ref IsRecipeOpened, value);
            }
        }

        /// <summary>
        /// is Recipe Opened?.
        /// </summary>
        public long DummyProcessLockId
        {
            get { return dummyProcessLockId; }
            set
            {
                Set(() => DummyProcessLockId, ref dummyProcessLockId, value);
            }
        }


        /// <summary>
        /// Recipe Template
        /// </summary>
        public RecipeTemplate processRecipeTemplate
        {
            get { return ProcessRecipeTemplate; }
            set
            {
                Set(() => processRecipeTemplate, ref ProcessRecipeTemplate, value);
            }
        }

        /// <summary>
        /// Recipe Template
        /// </summary>
        public ProcessRecipe DummyProcessRecipe
        {
            get { return dummyProcessRecipe; }
            set
            {
                Set(() => DummyProcessRecipe, ref dummyProcessRecipe, value);
            }
        }

        /// <summary>
        /// processRecipeViewModel for  datagrid
        /// </summary>
        public ObservableCollection<ExpandoObject> ProcessRecipeViewModel
        {
            get { return processRecipeViewModel; }
            set
            {
                Set(() => ProcessRecipeViewModel, ref processRecipeViewModel, value);
            }
        }

        /// <summary>
        /// processRecipeViewModel for  datagrid
        /// </summary>
        public ObservableCollection<string> EPDConfigList
        {
            get { return epdConfigList; }
            set
            {
                Set(() => EPDConfigList, ref epdConfigList, value);
            }
        }

        /// <summary>
        /// processRecipeViewModel for  datagrid
        /// </summary>
        public ObservableCollection<string> Allfolder
        {
            get { return allfolder; }
            set
            {
                Set(() => Allfolder, ref allfolder, value);
            }
        }
        /// <summary>
        /// ColumeModels for  datagrid row 
        /// </summary>
        public List<ColumeModel> ColumeModels
        {
            get { return columeModels; }
            set
            {
                Set(() => ColumeModels, ref columeModels, value);
            }
        }

        /// <summary>
        ///  the current job associated with the Recipe Location.
        /// </summary>
        /// <remarks>Setting this property will generate a <see cref="BaseNotifyPropertyChanged.PropertyChanged"/> event.</remarks>
        public string RecipeLocation
        {
            get { return recipeLocation; }
            set
            {
                Set(() => RecipeLocation, ref recipeLocation, value);
            }
        }


        private IRecipeTreeViewViewModel recipeTreeViewViewModel;
        /// <summary>
        /// Get and set the ViewModel for a tree view of the installed recipes.
        /// </summary>
        /// <remarks>Setting this property will generate the <see cref="BaseNotifyPropertyChanged.PropertyChanged"/> event.</remarks>
        public IRecipeTreeViewViewModel RecipeTreeViewViewModel
        {
            get { return recipeTreeViewViewModel; }
            set { Set(() => RecipeTreeViewViewModel, ref recipeTreeViewViewModel, value); }
        }
        /// <summary>
        /// query from recipe name
        /// </summary>
        public string SearchRecipe
        {
            get { return searchRecipe; }
            set
            {
                Set(() => SearchRecipe, ref searchRecipe, value);
            }
        }

        /// <summary>
        /// Create process user
        /// </summary>
        public string CreatedBy
        {
            get { return createdBy; }
            set
            {
                Set(() => CreatedBy, ref createdBy, value);
            }
        }

        /// <summary>
        /// Create process time
        /// </summary>
        public string CreateTime
        {
            get { return createTime; }
            set
            {
                Set(() => CreateTime, ref createTime, value);
            }
        }


        /// <summary>
        /// modify process time
        /// </summary>
        public string ModifyTime
        {
            get { return modifyTime; }
            set
            {
                Set(() => ModifyTime, ref modifyTime, value);
            }
        }

        /// <summary>
        /// modify process time
        /// </summary>
        public string Comments
        {
            get { return comments; }
            set
            {
                Set(() => Comments, ref comments, value);
            }
        }

        /// <summary>
        /// create Process Name.
        /// </summary>
        public string createProcessName
        {
            get { return CreateProcessName; }
            set
            {
                Set(() => createProcessName, ref CreateProcessName, value);
            }
        }
        /// <summary>
        /// Button  is enable.
        /// </summary>
        /// <remarks>When the view model sets this property, a <see cref="BaseNotifyPropertyChanged.PropertyChanged"/> event will be raised.</remarks>
        public bool ButtonIsView
        {
            get { return buttonIsView; }
            private set { Set(() => ButtonIsView, ref buttonIsView, value); }
        }

        /// <summary>
        /// Button EPDConfig is enable.
        /// </summary>
        /// <remarks>When the view model sets this property, a <see cref="BaseNotifyPropertyChanged.PropertyChanged"/> event will be raised.</remarks>
        public bool EPDConfigEnable
        {
            get { return epdConfigEnable; }
            set { Set(() => EPDConfigEnable, ref epdConfigEnable, value); }
        }

        /// <summary>
        /// query from recipe name
        /// </summary>
        public string DummyRecipeName
        {
            get { return dummyRecipeName; }
            set
            {
                Set(() => DummyRecipeName, ref dummyRecipeName, value);
            }
        }
        /// <summary>
        /// Command to send the message.
        /// </summary>
        public ICommand QueryRecipeCommand
        {
            get { return queryRecipeCommand; }
        }
        private bool isUseFomattedRecipeTransfer;
        /// <summary>
        /// Get and set flag to use formatted recipe transfers
        /// </summary>
        /// <remarks>Setting this property will generate the <see cref="BaseNotifyPropertyChanged.PropertyChanged"/> event.</remarks>
        public bool IsUseFomattedRecipeTransfer
        {
            get { return isUseFomattedRecipeTransfer; }
            set { Set(() => IsUseFomattedRecipeTransfer, ref isUseFomattedRecipeTransfer, value); }
        }

        #endregion

        #region Methods

        private void RecipeFilterFolder(RecipeFolderViewModel folder)
        {
            for (int i = 0; i < folder.Children.Count; i++)
            {
                RecipeFolderViewModel recipe = folder.Children[i] as RecipeFolderViewModel;
                if (recipe.IsAssigned())
                {
                    RecipeFilterFolder(recipe);
                }
                else
                {
                    RecipeViewModel recipeView = folder.Children[i] as RecipeViewModel;
                    if (recipeView.IsAssigned())
                    {
                        if (recipeView.RecipeFullPathName == DummyRecipeName)
                        {
                            IsRecipeDeleted = false;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Method overridden to subscribe to the <see cref="IOIClient.JobsChanged"/> event
        /// when the control is visible, and unsubscribe when the control is not visible.
        /// </summary>
        protected override void ControlIsVisibleChanged()
        {
            base.ControlIsVisibleChanged();

            if (ControlIsVisible)
            {
                if (DummyRecipeName != null && DummyRecipeName != "")
                {
                    if (columeModels.Count > 0)
                    {
                        try
                        {
                            IsRecipeDeleted = true;
                            if (RecipeTreeViewViewModel != null && RecipeTreeViewViewModel.RecipeFolders != null)
                            {
                                for (int i = 0; i < RecipeTreeViewViewModel.RecipeFolders.Count; i++)
                                {
                                    RecipeFilterFolder(RecipeTreeViewViewModel.RecipeFolders[i]);
                                }
                            }
                            if (IsRecipeDeleted)  //recipe is deleted
                            {
                                CancelAllProcessAction.Invoke();
                            }
                            else
                            {
                                DummyProcessLockId = OIClient.Service.LockRecipe(DummyRecipeName);
                            }
                            IsRecipeDeleted = true;
                        }
                        catch (Exception)
                        {
                            CancelAllProcessAction.Invoke();
                        }
                    }
                }
            }
            else
            {
                if(DummyRecipeName !=null && DummyRecipeName !="")
                OIClient.Service.UnlockRecipe(DummyRecipeName);
            }
        }

        private void RecipeTreeViewViewModelOnSelectionChanged(object sender, EventArgs args)
        {
            RecipeToSend = RecipeTreeViewViewModel.SelectedItem != null ? RecipeTreeViewViewModel.SelectedItem.RecipeFullPathName : string.Empty;
            GetSelectedRecipeFolder(RecipeTreeViewViewModel.RecipeFolders);
            if (RecipeToSend == "")
            {
                if (ColumeModels.Count != 0)
                {
                    CreateEnable = false;
                }
                else
                {
                    CreateEnable = true;
                }
                EditEnable = false;
                DeleteEnable = false;
            }
            else if (RecipeToSend != "" && ProcessRecipeIsEditing == false)
            {
                DeleteEnable = true;
                EditEnable = true;
                CreateEnable = false;
            }
        }

        private void GetSelectedRecipeFolder(IEnumerable<ITreeViewItemViewModel> recipeTree)
        {
            foreach (var treeNode in recipeTree)
            {
                if (treeNode.IsSelected && treeNode is RecipeViewModel)
                {
                    break;
                }

                var folderNode = treeNode as RecipeFolderViewModel;
                if (folderNode.IsAssigned())
                {
                    if (folderNode.Level == 3 && !Allfolder.Contains(folderNode.RecipeFullFolderName))
                        Allfolder.Add(folderNode.RecipeFullFolderName);
                    if (folderNode.IsSelected)
                    {
                        RecipeFullFolderName = folderNode.RecipeFullFolderName;
                        if (RecipeFullFolderName.Contains(".rcp"))
                        {
                            CreateEnable = false;
                        }
                    }
                    // ReSharper disable once PossibleNullReferenceException
                    GetSelectedRecipeFolder(folderNode.Children);
                }
            }
        }

        /// <summary>
        /// This method is called when the connection to the OIServer changes to Connected.
        /// This class has overridden <see cref="WpfBaseControlViewModel.Connected"/> to configure
        /// the load ports and data list views.
        /// </summary>
        /// <param name="system">Location of the OIServer</param>
        /// <param name="state">Connection state, will always be ConnectionState.Connected.</param>
        protected override void Connected(string system, ConnectionState state)
        {
            base.Connected(system, state);
            CreateEnable = true;
            EditEnable = false;
            DeleteEnable = false;
            CancelEnable = false;
            AddStepEnable = false;
            RemoveStepEnable = false;
            CopyStepEnable = false;
            PasteStepEnable = false;
            MoveStepEnable = false;
            SaveEnable = false;
            SaveAsEnable = false;
            ShowOESParamEnable = false;
            RestoreEnable = false;
            ProcessRecipeIsEditing = false;
            EPDConfigEnable = false;
            RecipeTreeViewViewModel recipeTreeViewViewModel = HelperExtensions.Initialize(new RecipeTreeViewViewModel(RecipeType.Process, "Engineering",true));
            RecipeTreeViewViewModel = HelperExtensions.Initialize(recipeTreeViewViewModel);
            RecipeTreeViewViewModel.SelectionChanged += RecipeTreeViewViewModelOnSelectionChanged;
        }


        private void CreateRecipeProcess()
        {
            if (RecipeFullFolderName.ToString() == "" || (!RecipeFullFolderName.Contains("Process") && !RecipeFullFolderName.Contains("DryClean")))
            {
                //MessageBox.Show("New recipe can't be created,there is not select right folder!", "Recipe Create Error", MessageBoxButton.OK);
                MessageBox.Show(LocalizationManager.GetResourceString("New recipe can't be created,there is not select right folder!"),
                    LocalizationManager.GetResourceString("Recipe create error"), MessageBoxButton.OK);
                return;
            }
            RecipeLocation = RecipeFullFolderName;
            if (RecipeToSend.IsAssigned() && RecipeToSend != "")
            {
                RecipeLocation = "";
                string[] parts = RecipeToSend.Split('\\');
                //循环输出分割后的结果
                for (int i = 0; i < parts.Length - 1; i++)
                {
                    RecipeLocation = RecipeLocation + parts[i] + "\\";
                }
                RecipeLocation.Trim('\\');
            }
            CreateProcessRecipeDialog dialog = new CreateProcessRecipeDialog(RecipeLocation, RecipeTreeViewViewModel,
                LocalizationManager.GetResourceString("Create process recipe"));
            dialog.Accept += new System.EventHandler(Win_accept);
            dialog.ShowDialog();
            if (!string.IsNullOrEmpty(CreateProcessName))
                CreateRecipeAction.Invoke();
        }

        private void Win_accept(object sender, System.EventArgs e)
        {
            if ((string)sender == "*")
            { CreateProcessName = ""; }
            else
            {
                CreateProcessName = (string)sender + ".rcp";
            }
        }

        private void Saveasaccept(object sender, System.EventArgs e)
        {
            CreateProcessName = ((string)sender).Split(':')[1] + ".rcp";
            RecipeFullFolderName = ((string)sender).Split(':')[0];
            RecipeLocation = RecipeFullFolderName;
        }
        private void RecipeFilter()
        {
            RecipeTreeViewViewModel.RecipeFolderFilter(SearchRecipe);
        }


        private void RecipeFilterFolder(RecipeFolderViewModel folder, int folderlevel)
        {
            if (string.IsNullOrEmpty(SearchRecipe))
            { return; }
            for (int i = 0; i < folder.Children.Count; i++)
            {
                RecipeFolderViewModel recipe = folder.Children[i] as RecipeFolderViewModel;
                if (recipe.IsAssigned())
                {
                    RecipeFilterMultiFolder(recipe);
                }
                else
                {
                    RecipeViewModel recipeView = folder.Children[i] as RecipeViewModel;
                    if (!recipeView.RecipeName.Contains(SearchRecipe))
                    {
                        RecipeTreeViewViewModel.RecipeFolders[folderlevel].deleteChild(RecipeTreeViewViewModel.RecipeFolders[folderlevel].Children[i]);
                        RecipeFilterFolder(RecipeTreeViewViewModel.RecipeFolders[folderlevel], folderlevel);
                    }
                }
            }

        }

        private void RecipeFilterMultiFolder(RecipeFolderViewModel folder)
        {
            for (int i = 0; i < folder.Children.Count; i++)
            {
                RecipeFolderViewModel recipe = folder.Children[i] as RecipeFolderViewModel;
                if (recipe.IsAssigned())
                {
                    RecipeFilterMultiFolder(recipe);
                }
                else
                {
                    RecipeViewModel recipeView = folder.Children[i] as RecipeViewModel;
                    if (!recipeView.RecipeName.Contains(SearchRecipe))
                    {
                        folder.deleteChild(folder.Children[i]);
                    }
                }
            }

        }


        private void UpdateCommandStatus()
        {
            sendCommand.SetDomainRuleEnabled(!string.IsNullOrEmpty(RecipeToSend));
        }
        private void PerformSend()
        {
            PerformRecipeCommand("SendRecipe", RecipeToSend);
        }


        private void PerformRecipeCommand(string command, string recipeName)
        {
            if (string.IsNullOrEmpty(command) || string.IsNullOrEmpty(recipeName))
                return;

            var parms = new Dictionary<string, NaValue>();
            parms["RecipeName"] = new AValue(recipeName);
            parms["UseFormattedTxfer"] = new BoValue(IsUseFomattedRecipeTransfer);
            ExecuteCommand("FA", command, parms);
        }

        private void ShowOESParamCommandProcess()
        {
            var command = new GuiCommand("OperateIOManager", "SetIOValue", string.Empty);
            command.Parameters = new Dictionary<string, NaValue>();
            string nameKey = PMNumber + ".CfgList_O";
            command.Parameters[nameKey] = new AValue("0");
            ExecuteCommand("OperateIOManager", "SetIOValue", command.Parameters);
            VariableInformation[] returnValue = null;
            string[] stringParamter = new string[1];
            stringParamter[0] = PMNumber + ".ConfigureList_I";
            returnValue = OIClient.Service.GetVariablesAsName(stringParamter);
            if (returnValue.IsAssigned())
            {
                EPDConfigEnable = true;
                if (returnValue.Count() > 0)
                {
                    string curRcpValue = returnValue[0].Value;
                    if (curRcpValue != "" && curRcpValue.Contains(","))
                    {
                        if (!EPDConfigList.Contains(""))
                        {
                            EPDConfigList.Add("");
                        }
                        string[] configLs = curRcpValue.Split(',');
                        foreach (string val in configLs)
                        {
                            if (!EPDConfigList.Contains(val))
                                EPDConfigList.Add(val);
                        }
                        for (int i = EPDConfigList.Count - 1; i >= 0; i--)
                        {
                            if (EPDConfigList[i] != "" && !configLs.Contains(EPDConfigList[i]))
                                EPDConfigList.Remove(EPDConfigList[i]);
                        }
                    }
                    else
                    {
                        for (int i = EPDConfigList.Count - 1; i >= 0; i--)
                        {
                            if (EPDConfigList[i] != "")
                                EPDConfigList.Remove(EPDConfigList[i]);
                        }
                    }
                }
               else
                {
                    EPDConfigList.Clear();
                    EPDConfigList.Add("");
                } 
                ShowOESParamAction.Invoke();
            }
        }

        private void RestoreProcessRecipeStep()
        {
            RestoreProcessAction.Invoke();
        }
        private void AddProcessRecipeStep()
        {
            AddStepAction.Invoke();
        }
        private void MoveProcessRecipeStep()
        {
            MoveStepAction.Invoke();
        }
        private void RemoveProcessRecipeStep()
        {
            RemoveStepAction.Invoke();
        }
        private void CopyProcessRecipeStep()
        {
            CopyStepAction.Invoke();
        }
        private void PasteProcessRecipeStep()
        {
            PasteStepAction.Invoke();
        }
        private void SaveProcess()
        {
            SaveProcessAction.Invoke();
            // RecipeFilter();
        }

        private void EditProcess()
        {
            EditProcessAction.Invoke();
        }

        private void ConcelProcess()
        {
            CancelProcessAction.Invoke();
        }
        private void DeleteProcess()
        {
            DeleteProcessAction.Invoke();
        }
        private void SaveAsProcess()
        {
            CreateProcessName = null;
            CreateProcessRecipeDialog dialog = new CreateProcessRecipeDialog(allfolder, RecipeTreeViewViewModel);
            dialog.Saveas += new System.EventHandler(Saveasaccept);
            dialog.ShowDialog();
            if (CreateProcessName != null)
                SaveAsProcessAction.Invoke();
        }

        #endregion

    }

3xaml

<ctrls:WpfBaseControl x:Class="Naura.Framework.UI.Components.Screens.ProcessRecipeScreen"
             x:TypeArguments="sctrls:IProcessRecipeScreenViewModel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sctrls="clr-namespace:Naura.Framework.UI.Components.Screens"
             xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
             xmlns:ctrls="clr-namespace:Naura.Framework.UI.Common.Controls;assembly=Naura.Framework.UI.Common"
             xmlns:cultr="clr-namespace:Naura.Framework.UI.Common.Framework.Localization;assembly=Naura.Framework.UI.Common"
             xmlns:Policies="clr-namespace:Naura.Framework.UI.Common.Framework.Policies;assembly=Naura.Framework.UI.Common"
             xmlns:Recipe="clr-namespace:Naura.Framework.UI.Components.Controls.Recipe">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="400" Width="*"></ColumnDefinition>
            <ColumnDefinition Width="700"></ColumnDefinition>
            <ColumnDefinition  Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <WrapPanel Grid.Row="0" Grid.Column="0">
            <TextBox VerticalContentAlignment="Center" Height="25"  Text="{Binding SearchRecipe, UpdateSourceTrigger=PropertyChanged}"  
                     Margin="10,5,1,5"  HorizontalAlignment="Left" x:Name="Sear_Name" Width="240">
                <TextBox.Resources>
                    <Style TargetType="{x:Type Border}">
                        <Setter Property="CornerRadius" Value="5"/>
                    </Style>
                </TextBox.Resources>
            </TextBox>
            <Button Grid.Row="3" Grid.Column="2" Content="{cultr:Localize Search}"  Margin="3,5,3,3" Width="100"  Height="25"  HorizontalAlignment="Right"
                     Style="{StaticResource CommonButton}"  Command="{Binding QueryRecipeCommand}" ></Button>
        </WrapPanel>
        <ScrollViewer Grid.Row="1"  Margin="0,5,0,0"  VerticalAlignment="Top" Grid.Column="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <WrapPanel>
                <Recipe:RecipeTreeView  Background="Transparent"  VirtualizingPanel.VirtualizationMode="Recycling"  VirtualizingPanel.IsVirtualizing="True" 
                                    HorizontalAlignment="Stretch" Height="700"  Grid.Row="2" Grid.Column="0" Width="250"
                                    DataContext="{Binding RecipeTreeViewViewModel}"  />
                <StackPanel IsEnabled="{Binding ButtonIsView}" HorizontalAlignment="Right"  Width="120" Margin="10,0,0,0">
                    <Button  Style="{StaticResource CommonButton}"   Margin="0,50,0,16" Grid.Row="3" Grid.Column="2"  IsEnabled="{Binding CreateEnable}" Content="{cultr:Localize Create}"  Width="100"  Command="{Binding CreateCommand}" ></Button>
                    <Button   Style="{StaticResource CommonButton}"  Margin="0,0,0,16" Grid.Row="3" Grid.Column="2"  IsEnabled="{Binding EditEnable}" Content="{cultr:Localize Edit}"  Width="100"  Command="{Binding EditProcessCommand}" ></Button>
                    <Button  Style="{StaticResource CommonButton}"    Margin="0,0,0,16"  Grid.Row="3" Grid.Column="2"   IsEnabled="{Binding DeleteEnable}" Content="{cultr:Localize Delete}"   Width="100"  Command="{Binding DeleteProcessCommand}" ></Button>
                    <Button  Style="{StaticResource CommonButton}"    Margin="0,0,0,16"  Grid.Row="3" Grid.Column="2"  IsEnabled="{Binding CancelEnable}" Content="{cultr:Localize Cancel}"   Width="100"  Command="{Binding CancelProcessCommand}" ></Button>
                </StackPanel>
            </WrapPanel>
        </ScrollViewer>

        <WrapPanel Margin="16,0,0,0" VerticalAlignment="Center"  Grid.Row="0" Grid.Column="1">
            <Label  Content="{cultr:Localize Recipe Location:}" Height="26"></Label>
            <TextBox  VerticalContentAlignment="Center" IsReadOnly="true" Background="{DynamicResource DefaultHeaderBackground}" Width="150" ToolTip="{Binding RecipeLocation}" Text="{Binding RecipeLocation}"  >
                <TextBox.Resources>
                    <Style TargetType="{x:Type Border}">
                        <Setter Property="CornerRadius" Value="3"/>
                    </Style>
                </TextBox.Resources>
            </TextBox> 
            <Label  HorizontalAlignment="Right" Margin="100,0,0,0" Height="26" Content="{cultr:Localize Comment:}"></Label>
            <TextBox  HorizontalAlignment="Right"  VerticalContentAlignment="Center"  Background="{DynamicResource DefaultHeaderBackground}"  x:Name="Remarke" Width="150" ToolTip="{Binding Comments}"
                      Text="{Binding Comments}" >
                <TextBox.Resources>
                    <Style TargetType="{x:Type Border}">
                        <Setter Property="CornerRadius" Value="3"/>
                    </Style>
                </TextBox.Resources>
            </TextBox>
        </WrapPanel>

        <StackPanel  Margin="16,0,0,0" Grid.Row="1" Grid.Column="1">
            <TabControl    SelectionChanged="TabControl_SelectionChanged" 
                                           VirtualizingPanel.IsVirtualizing="True"  
                                       VirtualizingPanel.IsContainerVirtualizable="True"  
                                         Name="RecipeTabControl" Margin="0,10,0,10"  Height="650">
                <TabControl.Resources>
                    <Style TargetType="ItemsControl" x:Key="ToleranceRecipeControl">

                        <Setter Property="ItemsPanel">
                            <Setter.Value>
                                <ItemsPanelTemplate>

                                    <VirtualizingStackPanel Orientation="Horizontal"></VirtualizingStackPanel>
                                </ItemsPanelTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="ItemTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <Border Width="240"  Background="{DynamicResource DefaultHeaderBackground}"  BorderBrush="Gray"
                             BorderThickness="1,1,1,0" 
                             Margin="-6,-2,-6,-2">
                                        <StackPanel>
                                            <WrapPanel VerticalAlignment="Center">
                                                <RadioButton GroupName="RadioButton" IsChecked="{Binding IsCheck,Mode=TwoWay}" VerticalContentAlignment="Center" 
                                             Name="RButton" Margin="10,0,0,0"></RadioButton>
                                                <Label Height="26" Content="{Binding Columes}"></Label>
                                            </WrapPanel>
                                            <ItemsControl AlternationCount="2"  Style="{StaticResource TRecipeItemControl}" ItemsSource="{Binding RecipeInfos}"></ItemsControl>
                                        </StackPanel>
                                    </Border>
                                </DataTemplate>

                            </Setter.Value>
                        </Setter>
                        <Setter Property="Template">

                            <Setter.Value>
                                <ControlTemplate TargetType="ItemsControl">
                                    <Border BorderBrush="Black"
                            BorderThickness="0,0,1,0">
                                        <ScrollViewer BorderThickness="0,1,0,1" x:Name="TScroll"  ScrollChanged="SV2_ScrollChanged"  VirtualizingPanel.IsVirtualizing="True"   
                                           VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Pixel"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Auto"  Height="613" Width="540"
                                           HorizontalScrollBarVisibility="Visible"  >

                                            <ItemsPresenter />
                                        </ScrollViewer>
                                    </Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>

                    <Style TargetType="ItemsControl" x:Key="SetpointRecipeSingleControl">
                        <Setter Property="ItemsPanel">
                            <Setter.Value>
                                <ItemsPanelTemplate>
                                    <VirtualizingStackPanel Orientation="Horizontal"></VirtualizingStackPanel>
                                </ItemsPanelTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="ItemTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <Border Width="80"  Background="{DynamicResource DefaultHeaderBackground}"  BorderBrush="Gray"
                             BorderThickness="1,1,1,0" 
                             Margin="-6,-2,-6,-2">
                                        <StackPanel>
                                            <WrapPanel VerticalAlignment="Center">
                                                <RadioButton x:Name="RButton" GroupName="RadioButton" IsChecked="{Binding IsCheck,Mode=TwoWay}" VerticalContentAlignment="Center" Margin="10,0,0,0"></RadioButton>
                                                <Label  Height="26" Content="{Binding Columes}"></Label>
                                            </WrapPanel>
                                            <ItemsControl AlternationCount="2"  Style="{StaticResource RecipeItemControl}" ItemsSource="{Binding RecipeInfos}"></ItemsControl>
                                        </StackPanel>
                                    </Border>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="ItemsControl">
                                    <Border BorderBrush="Black"
                            BorderThickness="0,0,1,0">
                                        <ScrollViewer BorderThickness="0,1,0,1" x:Name="SScroll" ScrollChanged="Setpoint_ScrollChanged"   
                                                      VirtualizingPanel.IsVirtualizing="True"   VirtualizingStackPanel.VirtualizationMode="Recycling"
                                                      VirtualizingPanel.ScrollUnit="Item"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Auto"  
                                        Height="613" Width="540"
                                           HorizontalScrollBarVisibility="Visible"  Grid.Row="3" Grid.Column="0" >

                                            <ItemsPresenter />
                                        </ScrollViewer>
                                    </Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </TabControl.Resources>
                <TabItem  Style="{StaticResource RecipeStyle}"  Background="{DynamicResource DefaultHeaderBackground}"   Header="Setpoint">
                    <Grid   Visibility="{Binding ProcessRecipeIsEditing,Mode=TwoWay,Converter={StaticResource BooleanToVisibilityConverter}}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition ></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <ScrollViewer  ScrollChanged="scrowsetpoint_ScrollChanged" x:Name="scrowsetpoint" VirtualizingPanel.IsVirtualizing="True"   VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Pixel"  VerticalAlignment="Top"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Hidden"  
                                        Height="607" Width="140" HorizontalAlignment="Right"
                                           HorizontalScrollBarVisibility="Auto"  Grid.Row="3" Grid.Column="0" >
                            <ListView   BorderBrush="Black"  Grid.Column="0" HorizontalContentAlignment="Center"  
                                                        VerticalContentAlignment="Center" Width="140" MouseWheel="listview_MouseWheel"
                                                     x:Name="HeaderView"   Style="{StaticResource HeaderRecipeItemsControl}">
                            </ListView>
                        </ScrollViewer>
                        <ListView   HorizontalAlignment="Left" Grid.Column="1"   VerticalAlignment="Top"
                                                     x:Name="RecipeView"  Style="{StaticResource SetpointRecipeSingleControl}">
                        </ListView>
                    </Grid>
                </TabItem>
                <TabItem  Style="{StaticResource RecipeStyle}" Header="Tolerance">
                    <Grid    Visibility="{Binding ProcessRecipeIsEditing,Mode=TwoWay,Converter={StaticResource BooleanToVisibilityConverter}}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition ></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <ScrollViewer ScrollChanged="scrow_ScrollChanged"  x:Name="scrow" VirtualizingPanel.IsVirtualizing="True"   VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Pixel"  VerticalAlignment="Top"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Hidden"  
                                        Height="607" Width="140" HorizontalAlignment="Right"
                                           HorizontalScrollBarVisibility="Auto"  Grid.Row="3" Grid.Column="0" Margin="0">
                            <ListView  BorderBrush="Black"  Grid.Column="0" HorizontalContentAlignment="Center" 
                                                           VerticalContentAlignment="Center" Width="140" MouseWheel="listview_MouseWheel"
                                                     x:Name="ToleranceHeaderView"   Style="{StaticResource HeaderRecipeItemsControl}">
                            </ListView>
                        </ScrollViewer>
                        <ListView   HorizontalAlignment="Left" Grid.Column="1"    VerticalAlignment="Top"
                                                     x:Name="ToleranceRecipeView"  Style="{StaticResource ToleranceRecipeControl}" >
                        </ListView>
                    </Grid>
                </TabItem>
                <TabItem  Style="{StaticResource RecipeStyle}" Header="Dechuck">
                    <Grid  HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="{Binding ProcessRecipeIsEditing,Mode=TwoWay,Converter={StaticResource BooleanToVisibilityConverter}}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Border BorderThickness="1" BorderBrush="Black"  Grid.Column="0"></Border>
                        <Border BorderThickness="0,1,1,1" BorderBrush="Black"  Grid.Column="1"></Border>
                        <Label Height="26" Width="140" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Grid.Row="0" Grid.Column="0">DechuckMode</Label>
                        <ComboBox Width="80" Height="26" Name="CBDechuckMode" Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" >
                        </ComboBox>
                    </Grid>
                </TabItem>
            </TabControl>
            <WrapPanel DockPanel.Dock="Top">
                <Label Content="{cultr:Localize Created by:}"></Label>
                <Label Content="{Binding CreatedBy}"></Label>
                <Label Content="{cultr:Localize Create Time:}"></Label>
                <Label Content="{Binding CreateTime}"></Label>
                <Label Content="{cultr:Localize Last Modified:}"></Label>
                <Label Content="{Binding ModifyTime}"></Label>
            </WrapPanel>
        </StackPanel>


        <Grid Margin="16,30,16,0" Grid.Row="1" Grid.Column="2" VerticalAlignment="Top">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <Button Style="{StaticResource CommonButton}"    Height="26"  Grid.Row="0" x:Name="addStep"  IsEnabled="{Binding AddStepEnable}" Content="{cultr:Localize Add Step}"   Command="{Binding AddStepCommand}" ></Button>
            <Button Style="{StaticResource CommonButton}"  Margin="0,17,0,16"  Grid.Row="1"   IsEnabled="{Binding RemoveStepEnable}" Content="{cultr:Localize Remove Step}"   Command="{Binding RemoveStepCommand}" ></Button>
            <Button Style="{StaticResource CommonButton}"   Grid.Row="2"  Content="{cultr:Localize Copy }"  IsEnabled="{Binding CopyStepEnable}"  Command="{Binding CopyCommand}" ></Button>
            <Button Style="{StaticResource CommonButton}"   Margin="0,17,0,16"  Grid.Row="3"  Content="{cultr:Localize Paste}"  IsEnabled="{Binding PasteStepEnable}"   Command="{Binding PasteCommand}" ></Button>
            <Button Style="{StaticResource CommonButton}"   Grid.Row="4"  IsEnabled="{Binding MoveStepEnable}"  Content="{cultr:Localize Move...}" Command="{Binding MoveStepCommand}"></Button>
            <Border Grid.Row="5"   Margin="0,17,0,16" Grid.Column="0"   BorderBrush="{DynamicResource DefaultLineBackground}"  BorderThickness="1"></Border>
            <Button Style="{StaticResource CommonButton}"   Grid.Row="6"   IsEnabled="{Binding SaveEnable}"  Content="{cultr:Localize Save }"  Command="{Binding SaveProcessCommand}" ></Button>
            <Button Style="{StaticResource CommonButton}" Margin="0,17,0,16"   Grid.Row="7"   IsEnabled="{Binding SaveAsEnable}"  Content="{cultr:Localize Save As...}"  Command="{Binding SaveAsProcessCommand}" ></Button>
            <Border Grid.Row="8"   Grid.Column="0"  BorderBrush="{DynamicResource DefaultLineBackground}"  BorderThickness="1"></Border>
            <Button Style="{StaticResource CommonButton}"  Margin="0,17,0,16"  Grid.Row="9"   Command="{Binding ShowOESParamCommand}"  IsEnabled="{Binding SaveEnable}" Content="{cultr:Localize Show OES Param}" ></Button>
            <Button Style="{StaticResource CommonButton}"   Grid.Row="10"  IsEnabled="{Binding RestoreEnable}" Content="{cultr:Localize Restore}" Command="{Binding RestoreProcessCommand}"></Button>
            <!--<Button Style="{StaticResource CommonButton}"  Margin="0,17,0,16"   Grid.Row="11"  IsEnabled="{Binding CancelEnable}" Content="{cultr:Localize Cancel}"   Command="{Binding CancelProcessCommand}" ></Button>-->

        </Grid>
    </Grid>











    <!--<Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition  Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ScrollViewer Grid.Row="1" Grid.Column="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <StackPanel Grid.Column="0" Margin="20,0,10,0" Width="400">
                <GroupBox Header="{cultr:Localize Avaliable Recipes}" >
                    <WrapPanel>
                        <StackPanel HorizontalAlignment="Left">
                            <TextBox VerticalContentAlignment="Center" Height="25"  Text="{Binding SearchRecipe, UpdateSourceTrigger=PropertyChanged}"  Margin="10,5,1,5"  HorizontalAlignment="Left" x:Name="Sear_Name" Width="240">
                            </TextBox>
                            <Recipe:RecipeTreeView  VirtualizingPanel.VirtualizationMode="Recycling"  VirtualizingPanel.IsVirtualizing="True" HorizontalAlignment="Left"  Height="700" Width="240" MaxHeight="630" Margin="10,5,1,5" Grid.Row="2" Grid.Column="0" DataContext="{Binding RecipeTreeViewViewModel}"  />
                        </StackPanel>
                        <StackPanel HorizontalAlignment="Right" >
                            <Button Grid.Row="3" Grid.Column="2" Content="{cultr:Localize Search}"  Margin="3,5,3,3" Width="100"  Height="25"  Command="{Binding QueryRecipeCommand}" ></Button>
                            <StackPanel IsEnabled="{Binding ButtonIsView}">
                                <Button  Height="40" Margin="0,50,0,10" Grid.Row="3" Grid.Column="2"  IsEnabled="{Binding CreateEnable}" Content="{cultr:Localize Create}"  Width="100"  Command="{Binding CreateCommand}" ></Button>
                                <Button Height="40"  Margin="0,0,0,10" Grid.Row="3" Grid.Column="2"  IsEnabled="{Binding EditEnable}" Content="{cultr:Localize Edit}"  Width="100"  Command="{Binding EditProcessCommand}" ></Button>
                                <Button  Height="40"  Margin="0,0,0,10"  Grid.Row="3" Grid.Column="2"   IsEnabled="{Binding DeleteEnable}" Content="{cultr:Localize Delete}"   Width="100"  Command="{Binding DeleteProcessCommand}" ></Button>
                                <Button  Height="40" Margin="0,0,0,10"  Grid.Row="3" Grid.Column="2"  IsEnabled="{Binding CancelEnable}" Content="{cultr:Localize Cancel}"   Width="100"  Command="{Binding CancelProcessCommand}" ></Button>
                            </StackPanel>
                        </StackPanel>
                    </WrapPanel>
                </GroupBox>
            </StackPanel>
        </ScrollViewer>
        <DockPanel  Grid.Column="1" DockPanel.Dock="Left" >
            <GroupBox Header="{cultr:Localize Recipe Details}" >
                <DockPanel>

                    <Grid DockPanel.Dock="Top">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition></RowDefinition>
                        </Grid.RowDefinitions>
                        <StackPanel Grid.Row="0" Grid.Column="0"  VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                            <WrapPanel>
                                <Label  Content="{cultr:Localize Recipe Location}" Height="26" Width="120" Margin="0,0,0,10"></Label>
                                <Button IsEnabled="False" Height="26" Width="440" Content="{Binding RecipeLocation}"  ></Button>
                            </WrapPanel>
                            <WrapPanel>
                                <Label Height="26" Content="{cultr:Localize Comment}" Width="120"></Label>
                                <TextBox Height="26" x:Name="Remarke" Width="440" Text="{Binding Comments}" Background="Transparent"></TextBox>
                            </WrapPanel>
                            <TabControl     SelectionChanged="TabControl_SelectionChanged"
                                           VirtualizingPanel.IsVirtualizing="True"  
                                       VirtualizingPanel.IsContainerVirtualizable="True"  
                                         Name="RecipeTabControl" Margin="0,10,0,10"  Height="580">
                                <TabControl.Resources>
                                    <Style TargetType="ItemsControl" x:Key="ToleranceRecipeControl">

                                        <Setter Property="ItemsPanel">
                                            <Setter.Value>
                                                <ItemsPanelTemplate>

                                                    <VirtualizingStackPanel Orientation="Horizontal"></VirtualizingStackPanel>
                                                </ItemsPanelTemplate>
                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="ItemTemplate">
                                            <Setter.Value>
                                                <DataTemplate>
                                                    <Border Width="240"   BorderBrush="Gray"
                             BorderThickness="1,1,1,0" 
                             Margin="-6,-2,-6,-2">
                                                        <StackPanel>
                                                            <WrapPanel VerticalAlignment="Center">
                                                                <RadioButton GroupName="RadioButton" IsChecked="{Binding IsCheck,Mode=TwoWay}" VerticalContentAlignment="Center" 
                                             Name="RButton" Margin="10,0,0,0"></RadioButton>
                                                                <Label Height="26" Content="{Binding Columes}"></Label>
                                                            </WrapPanel>
                                                            <ItemsControl   Style="{StaticResource TRecipeItemControl}" ItemsSource="{Binding RecipeInfos}"></ItemsControl>
                                                        </StackPanel>
                                                    </Border>
                                                </DataTemplate>

                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="Template">

                                            <Setter.Value>
                                                <ControlTemplate TargetType="ItemsControl">
                                                    <Border BorderBrush="Black"
                            BorderThickness="0,0,1,0">
                                                        <ScrollViewer BorderThickness="0,1,0,1" x:Name="TScroll"  ScrollChanged="SV2_ScrollChanged"  VirtualizingPanel.IsVirtualizing="True"   VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Pixel"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Auto"  Height="550" Width="500"
                                           HorizontalScrollBarVisibility="Visible"  >

                                                            <ItemsPresenter />
                                                        </ScrollViewer>
                                                    </Border>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>

                                    <Style TargetType="ItemsControl" x:Key="SetpointRecipeSingleControl">
                                        <Setter Property="ItemsPanel">
                                            <Setter.Value>
                                                <ItemsPanelTemplate>
                                                    <VirtualizingStackPanel Orientation="Horizontal"></VirtualizingStackPanel>
                                                </ItemsPanelTemplate>
                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="ItemTemplate">
                                            <Setter.Value>
                                                <DataTemplate>
                                                    <Border Width="80"   BorderBrush="Gray"
                             BorderThickness="1,1,1,0" 
                             Margin="-6,-2,-6,-2">
                                                        <StackPanel>
                                                            <WrapPanel VerticalAlignment="Center">
                                                                <RadioButton x:Name="RButton" GroupName="RadioButton" IsChecked="{Binding IsCheck,Mode=TwoWay}" VerticalContentAlignment="Center" Margin="10,0,0,0"></RadioButton>
                                                                <Label  Height="26" Content="{Binding Columes}"></Label>
                                                            </WrapPanel>
                                                            <ItemsControl   Style="{StaticResource RecipeItemControl}" ItemsSource="{Binding RecipeInfos}"></ItemsControl>
                                                        </StackPanel>
                                                    </Border>
                                                </DataTemplate>
                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="ItemsControl">
                                                    <Border BorderBrush="Black"
                            BorderThickness="0,0,1,0">
                                                        <ScrollViewer BorderThickness="0,1,0,1" x:Name="SScroll" ScrollChanged="Setpoint_ScrollChanged"    VirtualizingPanel.IsVirtualizing="True"   VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Pixel"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Auto"  
                                        Height="550" Width="500"
                                           HorizontalScrollBarVisibility="Visible"  Grid.Row="3" Grid.Column="0" >

                                                            <ItemsPresenter />
                                                        </ScrollViewer>
                                                    </Border>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </TabControl.Resources>
                                <TabItem   Header="Setpoint">
                                    <Grid  Margin="0,0,0,0" Visibility="{Binding ProcessRecipeIsEditing,Mode=TwoWay,Converter={StaticResource BooleanToVisibilityConverter}}">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                                            <ColumnDefinition ></ColumnDefinition>
                                        </Grid.ColumnDefinitions>
                                        <ScrollViewer  ScrollChanged="scrowsetpoint_ScrollChanged" x:Name="scrowsetpoint" VirtualizingPanel.IsVirtualizing="True"   VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Pixel"  VerticalAlignment="Top"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Hidden"  
                                        Height="533" Width="140" HorizontalAlignment="Right"
                                           HorizontalScrollBarVisibility="Auto"  Grid.Row="3" Grid.Column="0" Margin="0,0,0,0">
                                            <ListView   BorderBrush="Black"  Grid.Column="0" HorizontalContentAlignment="Center"  
                                                        VerticalContentAlignment="Center" Width="140" MouseWheel="listview_MouseWheel"
                                                     x:Name="HeaderView"   Style="{StaticResource HeaderRecipeItemsControl}">
                                            </ListView>
                                        </ScrollViewer>
                                        <ListView   HorizontalAlignment="Left" Grid.Column="1" Margin="0,0,0,0"   VerticalAlignment="Top"
                                                     x:Name="RecipeView"  Style="{StaticResource SetpointRecipeSingleControl}">
                                        </ListView>
                                    </Grid>
                                </TabItem>
                                <TabItem Header="Tolerance">
                                    <Grid  Margin="0,0,0,0" Visibility="{Binding ProcessRecipeIsEditing,Mode=TwoWay,Converter={StaticResource BooleanToVisibilityConverter}}">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                                            <ColumnDefinition ></ColumnDefinition>
                                        </Grid.ColumnDefinitions>
                                        <ScrollViewer ScrollChanged="scrow_ScrollChanged"  x:Name="scrow" VirtualizingPanel.IsVirtualizing="True"   VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Pixel"  VerticalAlignment="Top"
                                           CanContentScroll="True"  VerticalScrollBarVisibility="Hidden"  
                                        Height="533" Width="140" HorizontalAlignment="Right"
                                           HorizontalScrollBarVisibility="Auto"  Grid.Row="3" Grid.Column="0" Margin="0,0,0,0">
                                            <ListView  BorderBrush="Black"  Grid.Column="0" HorizontalContentAlignment="Center" 
                                                           VerticalContentAlignment="Center" Width="140" MouseWheel="listview_MouseWheel"
                                                     x:Name="ToleranceHeaderView"   Style="{StaticResource HeaderRecipeItemsControl}">
                                            </ListView>
                                        </ScrollViewer>
                                        <ListView   HorizontalAlignment="Left" Grid.Column="1" Margin="0"   VerticalAlignment="Top"
                                                     x:Name="ToleranceRecipeView"  Style="{StaticResource ToleranceRecipeControl}" >
                                        </ListView>
                                    </Grid>
                                </TabItem>
                                <TabItem Header="Dechuck">
                                    <Grid HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="2" Height="25" Width="220" Margin="0,0,0,0" Visibility="{Binding ProcessRecipeIsEditing,Mode=TwoWay,Converter={StaticResource BooleanToVisibilityConverter}}">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition></ColumnDefinition>
                                            <ColumnDefinition></ColumnDefinition>
                                        </Grid.ColumnDefinitions>
                                        <Border BorderThickness="1" BorderBrush="Black"  Grid.Column="0"></Border>
                                        <Border BorderThickness="0,1,1,1" BorderBrush="Black"  Grid.Column="1"></Border>
                                        <Label Width="140" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Grid.Row="0" Grid.Column="0">DechuckMode</Label>
                                        <ComboBox Name="CBDechuckMode" Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" >
                                        </ComboBox>
                                    </Grid>
                                </TabItem>
                            </TabControl>
                        </StackPanel>
                        <StackPanel Grid.Column="1" Grid.Row="0" Margin="20,0,0,1" HorizontalAlignment="Left">
                            <Grid Margin="0,10,0,0">
                                <Grid.RowDefinitions>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                    <RowDefinition></RowDefinition>
                                </Grid.RowDefinitions>
                                <WrapPanel  Grid.Row="2" Grid.Column="0"  HorizontalAlignment="Center"  Margin="0,0,0,10">
                                    <Button x:Name="addStep" Width="110" Height="40" IsEnabled="{Binding AddStepEnable}" Content="{cultr:Localize Add Step}"  Margin="3"  Command="{Binding AddStepCommand}" ></Button>
                                    <Button Width="110" Height="40"  IsEnabled="{Binding RemoveStepEnable}" Content="{cultr:Localize Remove Step}"   Margin="3"  Command="{Binding RemoveStepCommand}" ></Button>
                                </WrapPanel>
                                <WrapPanel  Grid.Row="3" Grid.Column="0"  HorizontalAlignment="Center"   Margin="0,0,0,10">
                                    <Button Width="110" Height="40" Content="{cultr:Localize Copy }"  IsEnabled="{Binding CopyStepEnable}"  Margin="3"  Command="{Binding CopyCommand}" ></Button>
                                    <Button Width="110" Height="40" Content="{cultr:Localize Paste}"  IsEnabled="{Binding PasteStepEnable}"   Margin="3"  Command="{Binding PasteCommand}" ></Button>
                                </WrapPanel>
                                <Button Width="226" Height="40" Grid.Row="4"  Margin="0,0,0,10"   IsEnabled="{Binding MoveStepEnable}"  Content="{cultr:Localize Move To}"   Command="{Binding MoveStepCommand}" ></Button>
                                <WrapPanel  Grid.Row="5" Grid.Column="0"  HorizontalAlignment="Center"   Margin="0,0,0,10">
                                    <Button Width="108" Height="40"  Margin="0,0,10,0"    IsEnabled="{Binding SaveEnable}"   Content="{cultr:Localize Save }"    Command="{Binding SaveProcessCommand}" ></Button>
                                    <Button Width="108" Height="40"  Margin="0,0,0,0"  IsEnabled="{Binding SaveAsEnable}"   Content="{cultr:Localize Save As}"  Command="{Binding SaveAsProcessCommand}" ></Button>
                                </WrapPanel>
                                <Button Width="226" Height="40" Grid.Row="6"  Command="{Binding ShowOESParamCommand}"   IsEnabled="{Binding SaveEnable}"   Content="{cultr:Localize Show OES Param}"   Margin="3" ></Button>
                                <Button    Width="226" Height="40" Grid.Row="7"  IsEnabled="{Binding RestoreEnable}"  Content="{cultr:Localize Restore}"  Margin="3,10,3,3"  Command="{Binding RestoreProcessCommand}" ></Button>

                            </Grid>
                        </StackPanel>
                    </Grid>

                    <WrapPanel DockPanel.Dock="Top">
                        <Label Content="{cultr:Localize Created by:}"></Label>
                        <Label Content="{Binding CreatedBy}"></Label>
                        <Label Content="{cultr:Localize Create Time:}"></Label>
                        <Label Content="{Binding CreateTime}"></Label>
                        <Label Content="{cultr:Localize Last Modified:}"></Label>
                        <Label Content="{Binding ModifyTime}"></Label>
                    </WrapPanel>
                </DockPanel>
            </GroupBox>
        </DockPanel>

    </Grid>-->
</ctrls:WpfBaseControl>

4xaml.cs

   /// <summary>
    /// Interaction logic for ProcessRecipeScreen.xaml
    /// </summary>
    public partial class ProcessRecipeScreen
    {
        #region Fields
        /// <summary>
        /// header viewmodel
        /// </summary>
        ObservableCollection<GridHeaderClass> header = new ObservableCollection<GridHeaderClass>();
        /// <summary>
        /// RecipeInfos viewmodel
        /// </summary>
        ObservableCollection<RecipeInfo> RecipeInfos = new ObservableCollection<RecipeInfo>();
        /// <summary>
        /// RecipeModels viewmodel
        /// </summary>
        ObservableCollection<RecipeModel> RecipeModels = new ObservableCollection<RecipeModel>();
 
        /// <summary>
        /// Dechuck source list
        /// </summary>
        List<string> AllColumes = new List<string>();

        /// <summary>
        /// Dechuck source list
        /// </summary>
        ObservableCollection<string> DechuckSourceList = new ObservableCollection<string>();

        private int cureentIndex = -1;
        private bool IsCreate = false;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the ProcessRecipeScreen View with
        /// the corresponding ViewModel.
        /// </summary>
        /// <param name="viewModel">The View's corresponding ViewModel.</param> 
        public ProcessRecipeScreen(IProcessRecipeScreenViewModel viewModel) : this()
        {
            ViewModel = viewModel;
            ViewModel.ProcessRecipeViewModel = new ObservableCollection<ExpandoObject>();
            viewModel.CreateRecipeAction += CreateRecipe;
            viewModel.AddStepAction += AddProcessRecipeStep;
            viewModel.RemoveStepAction += RemoveProcessRecipeStep;
            viewModel.CopyStepAction += CopyProcessRecipeStep;
            viewModel.PasteStepAction += PasteProcessRecipeStep;
            viewModel.MoveStepAction += MoveProcessRecipeStep;
            viewModel.SaveAsProcessAction += SaveAsProcessAction;
            viewModel.SaveProcessAction += SaveProcessAction;
            viewModel.EditProcessAction += EditProcess;
            viewModel.DeleteProcessAction += DeleteProcess;
            viewModel.CancelProcessAction += ConcelProcess;
            viewModel.CancelAllProcessAction += ConcelAllProcess;
            viewModel.RestoreProcessAction += RestoreProcess;
            ViewModel.ShowOESParamAction += ShowOESParamProcess;
            cureentIndex = 0; 
            //IsCopy = false;
            //EPDConfigList = viewModel.EPDConfigList;
            viewModel.EPDConfigList.Add("");
            HeaderView.ItemsSource = header;
            RecipeView.ItemsSource = RecipeModels;

            ToleranceHeaderView.ItemsSource = header;
            ToleranceRecipeView.ItemsSource = RecipeModels;

            CBDechuckMode.ItemsSource = DechuckSourceList;
        }


        /// <summary>
        /// InitializeComponent
        /// </summary>
        public ProcessRecipeScreen()
        {
            InitializeComponent();

        }
        #endregion

        #region Properties
        #endregion

        #region Methods
        /// <summary>
        /// restor selected recipe
        /// </summary>
        public void RestoreProcess()
        {
            OIClient.Service.UnlockRecipe(this.ViewModel.DummyRecipeName);
            EditProcess();
        }

        /// <summary>
        /// Concel selected process 
        /// </summary>
        public void ConcelAllProcess()
        {
            OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
            ViewModel.ColumeModels.Clear();
            header.Clear();
            RecipeInfos.Clear();
            RecipeModels.Clear();
            AllColumes.Clear();
            this.ViewModel.Comments = "";
            this.ViewModel.CreatedBy = "";
            this.ViewModel.CreateTime = "";
            this.ViewModel.ModifyTime = "";
            this.ViewModel.RecipeLocation = "";
            this.ViewModel.PMNumber = "";
            ConcelAuthorityControl(); 
            if (ViewModel.RecipeToSend.Contains(".rcp") && IsCreate == false)
            {
                ViewModel.EditEnable = true;
                ViewModel.DeleteEnable = true;
                ViewModel.CreateEnable = false;
            }

        }

        /// <summary>
        /// Concel selected process 
        /// </summary>
        public void ConcelProcess()
        {

            if (MessageBox.Show(LocalizationManager.GetResourceString("Are you sure you want to unsave the current information?"),
                LocalizationManager.GetResourceString("Cancel"), MessageBoxButton.YesNo, MessageBoxImage.Information) == MessageBoxResult.Yes)
            {
                OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
                ViewModel.ColumeModels.Clear();
                header.Clear();
                RecipeInfos.Clear();
                RecipeModels.Clear();
                AllColumes.Clear();
                this.ViewModel.Comments = "";
                this.ViewModel.CreatedBy = "";
                this.ViewModel.CreateTime = "";
                this.ViewModel.ModifyTime = "";
                this.ViewModel.RecipeLocation = "";
                this.ViewModel.PMNumber = "";
                ConcelAuthorityControl(); 
                if (ViewModel.RecipeToSend.Contains(".rcp") && IsCreate == false)//Engineering\PM1\Process\12313.rcp
                {
                    ViewModel.EditEnable = true;
                    ViewModel.DeleteEnable = true;
                    ViewModel.CreateEnable = false;
                }
            }

        }

        /// <summary>
        /// delete selected process 
        /// </summary>
        public void ConcelProcessError()
        {
            OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
            ViewModel.ColumeModels.Clear();
            header.Clear();
            RecipeInfos.Clear();
            RecipeModels.Clear();
            AllColumes.Clear();

            this.ViewModel.Comments = "";
            this.ViewModel.CreatedBy = "";
            this.ViewModel.CreateTime = "";
            this.ViewModel.ModifyTime = "";
            this.ViewModel.RecipeLocation = "";
            this.ViewModel.PMNumber = "";
            ConcelAuthorityControl(); 
            if (ViewModel.RecipeToSend.Contains(".rcp") && IsCreate == false)//Engineering\PM1\Process\12313.rcp
            {
                ViewModel.EditEnable = true;
                ViewModel.DeleteEnable = true;
                ViewModel.CreateEnable = false;
            }
        }

        /// <summary>
        /// delete selected process 
        /// </summary>
        public void DeleteProcess()
        {
            if (!string.IsNullOrEmpty(ViewModel.RecipeToSend))
            {
                if (MessageBox.Show(LocalizationManager.GetResourceString("Are you sure you want to delete it?"),
                    LocalizationManager.GetResourceString("Delete"), MessageBoxButton.YesNo, MessageBoxImage.Information) == MessageBoxResult.Yes)
                {
                    OIClient.Service.DeleteRecipe(this.ViewModel.RecipeToSend);
                    ConcelAuthorityControl();
                }

            }
        }
        /// <summary>
        /// edit process recipe
        /// </summary>
        public void EditProcess()
        {
            header.Clear();
            RecipeInfos.Clear(); 
            RecipeModels.Clear(); 
            AllColumes.Clear(); 
            DechuckSourceList.Clear();
            ViewModel.EPDConfigEnable = false;
            //OIClient.Service.UnlockRecipe(this.ViewModel.DummyRecipeName);
            if (!ViewModel.EPDConfigList.Contains(""))
            {
                ViewModel.EPDConfigList.Add("");
            }
            else
            {
                ViewModel.EPDConfigList[0] = "";
            }
            int maxcount = ViewModel.EPDConfigList.Count;
            if (ViewModel.EPDConfigList.Count > 1)
                for (int i = 0; i < maxcount; i++)
                {
                    if (ViewModel.EPDConfigList.Count > 1)
                        ViewModel.EPDConfigList.RemoveAt(1);
                };
            IsCreate = false; 
            ViewModel.ColumeModels.Clear();
            header.Clear();
            RecipeInfos.Clear();
            RecipeModels.Clear();
            AllColumes.Clear();
            this.ViewModel.Comments = "";
            this.ViewModel.CreatedBy = "";
            this.ViewModel.CreateTime = "";
            this.ViewModel.ModifyTime = "";
            this.ViewModel.RecipeLocation = "";
            if (ViewModel.RecipeToSend == null)
            {
                MessageBox.Show(LocalizationManager.GetResourceString("No recipe selected."), LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                return;
            }
            this.ViewModel.DummyRecipeName = ViewModel.RecipeToSend;

            // Lock recipe while editing.
            try
            {
                ViewModel.DummyProcessLockId = OIClient.Service.LockRecipe(this.ViewModel.DummyRecipeName);
            }
            catch (Exception ex)
            {
                Log.WriteExceptionCatch(ViewModel.Caption, ex);
                MessageBox.Show(string.Format(LocalizationManager.GetResourceString("Can not edit recipe: {0}."), ex.Message), LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                this.ViewModel.DummyRecipeName = string.Empty;
                return;
            }
            ViewModel.isRecipeOpened = true;
            string recipeFolder = "";
            string[] FolderArray = this.ViewModel.DummyRecipeName.Split('\\');
            for (int i = 0; i < FolderArray.Length - 1; i++)
            {
                recipeFolder = recipeFolder + FolderArray[i] + "\\";
            }
            recipeFolder.TrimEnd('\\');

            string[] rcps = OIClient.Service.ListRecipes(recipeFolder, RecipeType.Template, false);

            string template = "";

            foreach (string val in rcps)
            {
                if (val.EndsWith(Recipe.RcpTemplate))
                {
                    template = val;
                    break;
                }
            }
            byte[] templateBody = null;
            RecipeTemplate rcp = null;
            try
            {
                templateBody = OIClient.Service.GetRecipe(template);
                rcp = RecipeTemplate.CreateFromBuffer(templateBody);
            }
            catch (Exception ex)
            {
                Log.WriteExceptionCatch(ViewModel.Caption, ex);
                MessageBox.Show(string.Format(LocalizationManager.GetResourceString("Can not open recipe template body. {0}."), ex.Message), LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                //CustomMessageBox.Show(Localization.Service.GetResourceString("Can not open recipe template body." + ex.Message), DefaultScreenValues.DummyModuleRecipeEditorScreen, MessageBoxButtons.OK);
                OIClient.Service.UnlockRecipe(this.ViewModel.DummyRecipeName);
                ViewModel.isRecipeOpened = false;
                return;
            }
            // Display recipe contents.
            byte[] recipeBody = null;
            try
            {
                recipeBody = OIClient.Service.GetRecipe(this.ViewModel.DummyRecipeName);
                if (recipeBody == null)
                {
                    MessageBox.Show(LocalizationManager.GetResourceString("Can not retrieve recipe body."), LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                    //CustomMessageBox.Show(Localization.Service.GetResourceString("Can not retrieve recipe body."), DefaultScreenValues.DummyModuleRecipeEditorScreen, MessageBoxButtons.OK);
                    OIClient.Service.UnlockRecipe(this.ViewModel.DummyRecipeName);
                    ViewModel.isRecipeOpened = false;
                    return;
                }
            }
            catch (Exception ex)
            {
                Log.WriteExceptionCatch(ViewModel.Caption, ex);
                MessageBox.Show(LocalizationManager.GetResourceString("Failed to get recipe body from the Recipe Manager.  The recipe may be missing or corrupt."),
                    LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                //CustomMessageBox.Show(Localization.Service.GetResourceString("Failed to get recipe body from the Recipe Manager.  The recipe may be missing or corrupt."), DefaultScreenValues.DummyModuleRecipeEditorScreen, MessageBoxButtons.OK, MessageBoxIcon.Error);
                OIClient.Service.UnlockRecipe(this.ViewModel.DummyRecipeName);
                ViewModel.isRecipeOpened = false;
                return;
            }
            //针对.rcp
            if (this.ViewModel.DummyRecipeName.EndsWith(Recipe.ProcessExtension))
            {
                try
                {
                    ViewModel.DummyProcessRecipe = ProcessRecipe.CreateFromBuffer(recipeBody);
                    if (this.ViewModel.DummyProcessRecipe == null)
                    {
                        MessageBox.Show(LocalizationManager.GetResourceString("Can not restore the recipe."), LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                        //CustomMessageBox.Show(Localization.Service.GetResourceString("Can not restore the recipe."), DefaultScreenValues.DummyModuleRecipeEditorScreen, MessageBoxButtons.OK);
                        OIClient.Service.UnlockRecipe(this.ViewModel.DummyRecipeName);
                        ViewModel.isRecipeOpened = false;
                        return;
                    }
                }
                catch (Exception ex)
                {
                    Log.WriteExceptionCatch(ViewModel.Caption, ex);
                    MessageBox.Show(LocalizationManager.GetResourceString("Failed to create recipe from  byte buffer.  The recipe may be missing or corrupt."),
                        LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                    //CustomMessageBox.Show(Localization.Service.GetResourceString("Failed to create recipe from  byte buffer.  The recipe may be missing or corrupt."), DefaultScreenValues.DummyModuleRecipeEditorScreen, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
                    ViewModel.isRecipeOpened = false;
                    return;
                }
                try
                {
                    #region Maintain TempParameters enumeration type
                    if (rcp.TempParameters != null)
                    {
                        //循环添加表头
                        header.Add(
                            new GridHeaderClass()
                            {
                                GridHeader = "Parameter",
                                Index =3
                            });
                        header.Add(
                          new GridHeaderClass()
                          {
                              GridHeader = "Step Name",
                              Index=1
                          });
                        RecipeInfo recipeInfoStep = new RecipeInfo();
                        recipeInfoStep.ColueType = "TextBox";
                        recipeInfoStep.ParamKey = "step1";
                        recipeInfoStep.ParamName = "Step";
                        recipeInfoStep.ParamSoftToleranceKey = "Soft";
                        recipeInfoStep.ParamHardToleranceKey = "Hard";
                        recipeInfoStep.ContainHardSoft = false;
                        recipeInfoStep.RecipeParameter = null;
                        RecipeInfos.Add(recipeInfoStep);
                        for (int i = 0; i < rcp.TempParameters.Length; i++)
                        {
                            if (rcp.TempParameters[i].ParamName == "EPDConfig")
                            {
                                rcp.TempParameters[i].DiscriptionList = new List<string>(ViewModel.EPDConfigList);
                                rcp.TempParameters[i].Min = 0;
                                rcp.TempParameters[i].Max = 0;
                                rcp.TempParameters[i].DefaultValue = 0;
                            }
                            AllColumes.Add(rcp.TempParameters[i].ParamName);
                            if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                            {
                                if (this.IsNumber(rcp.TempParameters[i].DefaultValue))
                                {
                                    if (rcp.TempParameters[i].DiscriptionList.Contains(rcp.TempParameters[i].DefaultValue.ToString()))
                                    {
                                        if (Convert.ToInt32(rcp.TempParameters[i].DefaultValue) > Convert.ToInt32(rcp.TempParameters[i].DiscriptionList.Count))
                                        {
                                            for (int j = 0; j < rcp.TempParameters[i].DiscriptionList.Count; j++)
                                            {
                                                if (rcp.TempParameters[i].DefaultValue.ToString() == rcp.TempParameters[i].DiscriptionList[j])
                                                {
                                                    rcp.TempParameters[i].DefaultValue = j;

                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (Convert.ToInt32(rcp.TempParameters[i].DefaultValue) > Convert.ToInt32(rcp.TempParameters[i].DiscriptionList.Count) || Convert.ToInt32(rcp.TempParameters[i].DefaultValue) < 0)
                                        {
                                            rcp.TempParameters[i].DefaultValue = 0;
                                        }
                                    }
                                }
                            }
                            #region
                            //表头数据
                            RecipeInfo recipeInfo = new RecipeInfo();
                            recipeInfo.ComBoxList = new ObservableCollection<string>();
                            if (rcp.TempParameters[i].ParamName != "DechuckMode" && !rcp.TempParameters[i].ParamName.Contains("SoftTolerance")
                                && !rcp.TempParameters[i].ParamName.Contains("HardTolerance"))
                            {
                                header.Add(new GridHeaderClass()
                                {
                                    GridHeader = rcp.TempParameters[i].ParamName,
                                    Index = i%2
                                });
                                if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                                {
                                    recipeInfo.ColueType = "Combox";
                                    foreach (string item in rcp.TempParameters[i].DiscriptionList)
                                    {
                                        recipeInfo.ComBoxList.Add(item);
                                    }
                                    recipeInfo.ParamKey = rcp.TempParameters[i].DiscriptionList[Convert.ToInt32(rcp.TempParameters[i].DefaultValue)];
                                }
                                else
                                {
                                    recipeInfo.ColueType = "TextBox";
                                    recipeInfo.ParamKey = rcp.TempParameters[i].DefaultValue.ToString();
                                }
                                recipeInfo.ParamName = rcp.TempParameters[i].ParamName;
                                recipeInfo.RecipeParameter = rcp.TempParameters[i];
                                recipeInfo.ContainHardSoft = false;
                                RecipeInfos.Add(recipeInfo);
                            }
                            else if (rcp.TempParameters[i].ParamName != "DechuckMode" && (rcp.TempParameters[i].ParamName.Contains("SoftTolerance")
                                || rcp.TempParameters[i].ParamName.Contains("HardTolerance")))
                            {
                                for (int r = 0; r < RecipeInfos.Count; r++)
                                {
                                    if (rcp.TempParameters[i].ParamName.Contains("SoftTolerance") &&
                                        RecipeInfos[r].ParamName == rcp.TempParameters[i].ParamName.Split('_')[0])
                                    {
                                        RecipeInfos[r].ParamSoftToleranceKey = rcp.TempParameters[i].DefaultValue.ToString();
                                        RecipeInfos[r].ContainHardSoft = true;
                                    }
                                    else if (rcp.TempParameters[i].ParamName.Contains("HardTolerance") &&
                                        RecipeInfos[r].ParamName == rcp.TempParameters[i].ParamName.Split('_')[0])
                                    {
                                        RecipeInfos[r].ParamHardToleranceKey = rcp.TempParameters[i].DefaultValue.ToString();
                                        RecipeInfos[r].ContainHardSoft = true;
                                    }
                                }
                            }
                            else if (rcp.TempParameters[i].ParamName == "DechuckMode")
                            {
                                if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                                {
                                    foreach (string item in rcp.TempParameters[i].DiscriptionList)
                                    {
                                        DechuckSourceList.Add(item);
                                    }
                                    CBDechuckMode.Text = rcp.TempParameters[i].DiscriptionList[Convert.ToInt32(rcp.TempParameters[i].DefaultValue)];
                                }

                            }
                            #endregion
                        }
                    }
                    #endregion
                    //开始恢复数据
                    // Verify that this is a recipe for a Dummy Module.
                    if (ViewModel.DummyProcessRecipe.Processing != null)
                    {
                        this.ViewModel.CreatedBy = ViewModel.DummyProcessRecipe.CreatedBy;
                        this.ViewModel.CreateTime = ViewModel.DummyProcessRecipe.CreateTime;
                        this.ViewModel.ModifyTime = ViewModel.DummyProcessRecipe.ModifyTime;
                        this.ViewModel.Comments = ViewModel.DummyProcessRecipe.Comments;
                        int Colume = 1; 
                        foreach (ProcessStep step in ViewModel.DummyProcessRecipe.Processing.ProcessSteps)
                        {
                            ObservableCollection<RecipeInfo> recipeInfolist = new ObservableCollection<RecipeInfo>();
                            RecipeModel recipeModel = new RecipeModel();
                            recipeModel.Columes = Colume.ToString();
                            recipeModel.IsCheck = false;
                            RecipeInfo recipeInfoStep = new RecipeInfo();
                            recipeInfoStep.ColueType = "TextBox";
                            recipeInfoStep.ParamKey = step.Name;
                            recipeInfoStep.ParamName = "Step";
                            recipeInfoStep.ParamSoftToleranceKey = "Soft";
                            recipeInfoStep.ParamHardToleranceKey = "Hard";
                            recipeInfoStep.ContainHardSoft = false;
                            recipeInfoStep.RecipeParameter = null;
                            recipeInfolist.Add(recipeInfoStep);
                            if (AllColumes.Count == step.Arguments.Length && step.Arguments.Length == rcp.TempParameters.Length)
                            {
                              
                                for (int i = 0; i < step.Arguments.Length; i++)
                                {
                                    string columName = AllColumes[i];
                                    if (columName != "DechuckMode" && !columName.Contains("SoftTolerance") && !columName.Contains("HardTolerance"))
                                    {
                                        if (Colume == 1)
                                        {
                                            header.Add(new GridHeaderClass()
                                            {
                                                GridHeader = AllColumes[i],
                                            });
                                        }
                                        RecipeInfo recipe = new RecipeInfo();
                                        if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                                        {
                                            recipe.ComBoxList = new ObservableCollection<string>();
                                            recipe.ColueType = "Combox";
                                            foreach (string item in rcp.TempParameters[i].DiscriptionList)
                                            {
                                                recipe.ComBoxList.Add(item);
                                            }
                                            if (columName == "EPDConfig")
                                            {
                                                if (!recipe.ComBoxList.Contains(step.Arguments[i]))
                                                {
                                                    recipe.ComBoxList.Add(step.Arguments[i]);
                                                }
                                            }
                                            recipe.ParamKey = step.Arguments[i];
                                        }
                                        else
                                        {
                                            recipe.ColueType = "TextBox";
                                            recipe.ParamKey = step.Arguments[i];
                                        }
                                        recipe.ParamName = rcp.TempParameters[i].ParamName;
                                        recipe.RecipeParameter = rcp.TempParameters[i];
                                        recipe.ContainHardSoft = false;
                                        recipeInfolist.Add(recipe);
                                    }
                                    else
                                    {
                                        if (columName == "DechuckMode")
                                        {
                                            if (rcp.TempParameters[i].DiscriptionList.Count > 0 && DechuckSourceList.Count != 0)
                                            {
                                                foreach (string item in rcp.TempParameters[i].DiscriptionList)
                                                {
                                                    DechuckSourceList.Add(item);
                                                }
                                                CBDechuckMode.Text = step.Arguments[i];
                                            }
                                        }
                                        else
                                        {
                                            RecipeInfo recipeInfo = null;
                                            if (columName.Contains("SoftTolerance"))
                                            {
                                                string colum = AllColumes[i].Replace("_SoftTolerance", "");
                                                recipeInfo = recipeInfolist.Where(r => r.ParamName == colum).FirstOrDefault();
                                                if (recipeInfo != null)
                                                {
                                                    recipeInfo.ContainHardSoft = true;
                                                    recipeInfo.ParamSoftToleranceKey = step.Arguments[i];
                                                }
                                            }
                                            else if (columName.Contains("HardTolerance"))
                                            {
                                                string colum = AllColumes[i].Replace("_HardTolerance", "");
                                                recipeInfo = recipeInfolist.Where(r => r.ParamName == colum).FirstOrDefault();
                                                if (recipeInfo != null)
                                                {
                                                    recipeInfo.ContainHardSoft = true;
                                                    recipeInfo.ParamHardToleranceKey = step.Arguments[i];
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            recipeModel.RecipeInfos = recipeInfolist;
                            RecipeModels.Add(recipeModel);
                            Colume++;
                            //if (step.)
                            //{
                            //    if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                            //    {
                            //        foreach (string item in rcp.TempParameters[i].DiscriptionList)
                            //        {
                            //            DechuckSourceList.Add(item);
                            //        }
                            //        CBDechuckMode.Text = rcp.TempParameters[i].DiscriptionList[Convert.ToInt32(rcp.TempParameters[i].DefaultValue)];
                            //    }

                            //}
                        }
                        EditAuthorityControl();
                        ViewModel.RecipeLocation = recipeFolder;
                        //if ((recipeFolder.Contains("PM") || recipeFolder.Contains("TM")) && recipeFolder.Contains("\\"))
                        //{
                        //    string[] location = recipeFolder.Split('\\');
                        //    foreach (string item in location)
                        //    {
                        //        if (item.Contains("PM") || item.Contains("TM"))
                        //        {
                        //            ViewModel.PMNumber = item;
                        //        }
                        //    }

                        //}
                    }
                }
                catch (Exception ex)
                {
                    Log.WriteExceptionCatch(ViewModel.Caption, ex);
                    MessageBox.Show(LocalizationManager.GetResourceString("Specified recipe is not a valid recipe for a Dummy Module."),
                        LocalizationManager.GetResourceString("Recipe editor"), MessageBoxButton.OK);
                    OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
                    ViewModel.isRecipeOpened = false;
                    #region 
                    ViewModel.ColumeModels.Clear();
                    header.Clear();
                    RecipeInfos.Clear();
                    RecipeModels.Clear();
                    AllColumes.Clear();
                    this.ViewModel.Comments = "";
                    this.ViewModel.CreatedBy = "";
                    this.ViewModel.CreateTime = "";
                    this.ViewModel.ModifyTime = "";
                    this.ViewModel.RecipeLocation = "";
                    this.ViewModel.PMNumber = "";
                    ConcelAuthorityControl(); 
                    #endregion
                    return;
                }
            }
        }

        /// <summary>
        /// Clones the specified list.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="List">The list.</param>
        /// <returns>List{``0}.</returns>
        public static ObservableCollection<T> Clone<T>(object List)
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, List);
                objectStream.Seek(0, SeekOrigin.Begin);
                return formatter.Deserialize(objectStream) as ObservableCollection<T>;
            }
        } 
        #region 新逻辑
        /// <summary>
        /// 
        /// </summary>
        public void CreateRecipe()
        {
            AllColumes.Clear();
            RecipeInfos.Clear();
            RecipeModels.Clear();
            DechuckSourceList.Clear();
            header.Clear();
            if (!ViewModel.EPDConfigList.Contains(""))
            {
                ViewModel.EPDConfigList.Add("");
            }
            else
            {
                ViewModel.EPDConfigList[0] = "";
            }
            int maxcount = ViewModel.EPDConfigList.Count;
            if (ViewModel.EPDConfigList.Count > 1)
                for (int i = 0; i < maxcount; i++)
                {
                    if (ViewModel.EPDConfigList.Count > 1)
                        ViewModel.EPDConfigList.RemoveAt(1);
                };
            if (ViewModel.RecipeLocation.ToString() == "" || (!ViewModel.RecipeLocation.Contains("Process") && !ViewModel.RecipeLocation.Contains("DryClean")))
            {
                MessageBox.Show(LocalizationManager.GetResourceString("New recipe can't be created,there is not recipe template in this folder!"),
                    LocalizationManager.GetResourceString("Create process recipe"), MessageBoxButton.OKCancel);
                ViewModel.RecipeLocation = "";
                return;
            }
            IsCreate = true;
            string[] rcps = OIClient.Service.ListRecipes(ViewModel.RecipeLocation, RecipeType.Template, false);
            bool istemplate = false;
            string template = "";
            foreach (string val in rcps)
            {
                if (val.EndsWith(Recipe.RcpTemplate))
                {
                    istemplate = true;
                    template = val;
                    break;
                }
            }
            if (istemplate == true)
            {
                string recipeName = ViewModel.createProcessName;
                if (string.IsNullOrEmpty(recipeName))
                    return;
                // Combine the recipe name with the folder.
                ViewModel.DummyRecipeName = Path.Combine(ViewModel.RecipeLocation, ViewModel.createProcessName);
                try
                {
                    ViewModel.DummyProcessLockId = OIClient.Service.LockRecipe(ViewModel.DummyRecipeName);

                    ViewModel.DummyProcessRecipe = new ProcessRecipe();

                    byte[] recipeBody = null;
                    recipeBody = OIClient.Service.GetRecipe(template);

                    if (recipeBody == null)
                    {
                        OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
                        ViewModel.isRecipeOpened = false;
                        return;
                    }
                    RecipeTemplate rcp = RecipeTemplate.CreateFromBuffer(recipeBody);
                    if (rcp == null)
                    {
                        OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
                        ViewModel.isRecipeOpened = false;
                        return;
                    }
                    List<RecipeParameter[]> tempList = new List<RecipeParameter[]>();
                    #region Maintain TempParameters enumeration type
                    if (rcp.TempParameters != null)
                    {
                        //循环添加表头
                        header.Add(
                            new GridHeaderClass()
                            {
                                GridHeader = "Parameter",
                                Index =3
                            });
                        header.Add(
                          new GridHeaderClass()
                          {
                              GridHeader = "Step Name",
                              Index = 1
                          });
                        RecipeInfo recipeInfoStep = new RecipeInfo();
                        recipeInfoStep.ColueType = "TextBox";
                        recipeInfoStep.ParamKey = "step1";
                        recipeInfoStep.ParamName = "Step";
                        recipeInfoStep.ParamSoftToleranceKey = "Soft";
                        recipeInfoStep.ParamHardToleranceKey = "Hard";
                        recipeInfoStep.ContainHardSoft = false;
                        recipeInfoStep.RecipeParameter = null;
                        RecipeInfos.Add(recipeInfoStep);
                        for (int i = 0; i < rcp.TempParameters.Length; i++)
                        {
                            if (rcp.TempParameters[i].ParamName == "EPDConfig")
                            {
                                rcp.TempParameters[i].DiscriptionList = new List<string>(ViewModel.EPDConfigList);
                                rcp.TempParameters[i].Min = 0;
                                rcp.TempParameters[i].Max = 0;
                                rcp.TempParameters[i].DefaultValue = 0;
                            }
                            AllColumes.Add(rcp.TempParameters[i].ParamName);
                            if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                            {
                                if (this.IsNumber(rcp.TempParameters[i].DefaultValue))
                                {
                                    if (rcp.TempParameters[i].DiscriptionList.Contains(rcp.TempParameters[i].DefaultValue.ToString()))
                                    {
                                        if (Convert.ToInt32(rcp.TempParameters[i].DefaultValue) > Convert.ToInt32(rcp.TempParameters[i].DiscriptionList.Count))
                                        {
                                            for (int j = 0; j < rcp.TempParameters[i].DiscriptionList.Count; j++)
                                            {
                                                if (rcp.TempParameters[i].DefaultValue.ToString() == rcp.TempParameters[i].DiscriptionList[j])
                                                {
                                                    rcp.TempParameters[i].DefaultValue = j;

                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (Convert.ToInt32(rcp.TempParameters[i].DefaultValue) > Convert.ToInt32(rcp.TempParameters[i].DiscriptionList.Count) || Convert.ToInt32(rcp.TempParameters[i].DefaultValue) < 0)
                                        {
                                            rcp.TempParameters[i].DefaultValue = 0;
                                        }
                                    }
                                }
                            }
                            //表头数据
                            RecipeInfo recipeInfo = new RecipeInfo();
                            recipeInfo.ComBoxList = new ObservableCollection<string>();
                            if (rcp.TempParameters[i].ParamName != "DechuckMode" && !rcp.TempParameters[i].ParamName.Contains("SoftTolerance")
                                && !rcp.TempParameters[i].ParamName.Contains("HardTolerance"))
                            {
                                header.Add(new GridHeaderClass()
                                {
                                    GridHeader = rcp.TempParameters[i].ParamName,
                                    Index = i % 2
                                });
                                if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                                {
                                    recipeInfo.ColueType = "Combox";
                                    foreach (string item in rcp.TempParameters[i].DiscriptionList)
                                    {
                                        recipeInfo.ComBoxList.Add(item);
                                    }
                                    recipeInfo.ParamKey = rcp.TempParameters[i].DiscriptionList[Convert.ToInt32(rcp.TempParameters[i].DefaultValue)];
                                }
                                else
                                {
                                    recipeInfo.ColueType = "TextBox";
                                    recipeInfo.ParamKey = rcp.TempParameters[i].DefaultValue.ToString();
                                }
                                recipeInfo.ParamName = rcp.TempParameters[i].ParamName;
                                recipeInfo.RecipeParameter = rcp.TempParameters[i];
                                recipeInfo.ContainHardSoft = false;
                                RecipeInfos.Add(recipeInfo);
                            }
                            else if (rcp.TempParameters[i].ParamName != "DechuckMode" && (rcp.TempParameters[i].ParamName.Contains("SoftTolerance")
                                || rcp.TempParameters[i].ParamName.Contains("HardTolerance")))
                            {
                                for (int r = 0; r < RecipeInfos.Count; r++)
                                {
                                    if (rcp.TempParameters[i].ParamName.Contains("SoftTolerance") &&
                                        RecipeInfos[r].ParamName == rcp.TempParameters[i].ParamName.Split('_')[0])
                                    {
                                        RecipeInfos[r].ParamSoftToleranceKey = rcp.TempParameters[i].DefaultValue.ToString();
                                        RecipeInfos[r].ContainHardSoft = true;
                                    }
                                    else if (rcp.TempParameters[i].ParamName.Contains("HardTolerance") &&
                                        RecipeInfos[r].ParamName == rcp.TempParameters[i].ParamName.Split('_')[0])
                                    {
                                        RecipeInfos[r].ParamHardToleranceKey = rcp.TempParameters[i].DefaultValue.ToString();
                                        RecipeInfos[r].ContainHardSoft = true;
                                    }
                                }
                            }
                            else if (rcp.TempParameters[i].ParamName == "DechuckMode")
                            {
                                if (rcp.TempParameters[i].DiscriptionList.Count > 0)
                                {
                                    foreach (string item in rcp.TempParameters[i].DiscriptionList)
                                    {
                                        DechuckSourceList.Add(item);
                                    }
                                    CBDechuckMode.Text = rcp.TempParameters[i].DiscriptionList[Convert.ToInt32(rcp.TempParameters[i].DefaultValue)];
                                }

                            }
                        }
                    }
                    Stopwatch sw3 = new Stopwatch();
                    sw3.Start();
                    RecipeModels.Add(new RecipeModel()
                    {
                        Columes = "1",
                        IsCheck = false,
                        RecipeInfos = Clone<RecipeInfo>(RecipeInfos)
                    });
                    sw3.Stop();
                    Console.WriteLine($"DeepCopyByReflection 共耗时 {sw3.ElapsedMilliseconds} 毫秒");
                    #endregion
                }
                catch (Exception ex)
                {
                    Log.WriteExceptionCatch("ProcessRecipe", ex);
                    ViewModel.DummyRecipeName = string.Empty;
                    ViewModel.isRecipeOpened = false;
                    ConcelProcessError();

                    MessageBox.Show(string.Format(LocalizationManager.GetResourceString("New recipe can't be created:{0}."), ex.Message),
                        LocalizationManager.GetResourceString("Create process recipe"), MessageBoxButton.OKCancel);
                    return;
                }
            }
            else
            {
                MessageBox.Show(LocalizationManager.GetResourceString("New recipe can't be created,there is not recipe template in this folder!"),
                    LocalizationManager.GetResourceString("Create process recipe"), MessageBoxButton.OKCancel);
                ViewModel.RecipeLocation = "";
                return;
            }
            CreateAuthorityControl();
            ViewModel.EPDConfigEnable = true;
        }

        #endregion
        /// <summary>
        /// view button control.
        /// </summary>
        public void EditAuthorityControl()
        {
            CreateAuthorityControl();
            ViewModel.CreateEnable = false;
            ViewModel.ProcessRecipeIsEditing = true;
            ViewModel.RestoreEnable = true;
            ViewModel.RestoreEnable = true;
            ViewModel.EditEnable = false;
        }

        /// <summary>
        /// view button control.
        /// </summary>
        public void ConcelAuthorityControl()
        {
            ViewModel.CreateEnable = true;
            ViewModel.EditEnable = false;
            if (ViewModel.EditEnable)
            {
                ViewModel.EditEnable = true;
            }
            else
            {
                ViewModel.EditEnable = false;
            }
            if (ViewModel.CreateEnable)
            {
                ViewModel.CreateEnable = true;
            }
            else
            {
                ViewModel.CreateEnable = false;
            }
            ViewModel.DeleteEnable = false;
            ViewModel.CancelEnable = false;
            ViewModel.AddStepEnable = false;
            ViewModel.RemoveStepEnable = false;
            ViewModel.CopyStepEnable = false;
            ViewModel.PasteStepEnable = false;
            ViewModel.MoveStepEnable = false;
            ViewModel.SaveEnable = false;
            ViewModel.SaveAsEnable = false;
            ViewModel.ShowOESParamEnable = false;
            ViewModel.RestoreEnable = false;
            ViewModel.ProcessRecipeIsEditing = false;
        }

        /// <summary>
        /// view button control.
        /// </summary>
        public void CreateAuthorityControl()
        {
            ViewModel.CreateEnable = false;
            ViewModel.DeleteEnable = false;
            ViewModel.ProcessRecipeIsEditing = true;
            ViewModel.CancelEnable = true;
            ViewModel.AddStepEnable = true;
            ViewModel.RestoreEnable = false;
            ViewModel.RemoveStepEnable = true;
            ViewModel.CopyStepEnable = true;
            ViewModel.PasteStepEnable = true;
            ViewModel.MoveStepEnable = true;
            ViewModel.SaveAsEnable = true;
            ViewModel.SaveEnable = true;
        }

        /// <summary>
        /// add process recipe step
        /// </summary>
        public void AddProcessRecipeStep()
        {
            ObservableCollection<RecipeInfo> recipeInfos = Clone<RecipeInfo>(RecipeInfos);
            recipeInfos[0].ParamKey = "step" + (RecipeModels.Count + 1).ToString();
            RecipeModels.Add(new RecipeModel()
            {
                Columes = (RecipeModels.Count+1).ToString(),
                RecipeInfos = recipeInfos,
            });
        }

        /// <summary>
        /// remove process recipe step
        /// </summary>
        public void ShowOESParamProcess()
        {
            for (int i = 0; i < RecipeModels.Count; i++)
            {
                List<RecipeInfo> recipeInfos = RecipeModels[i].RecipeInfos.ToList();
                RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == "EPDConfig").FirstOrDefault();
                recipeInfo.ComBoxList.Clear();
                foreach (string item in ViewModel.EPDConfigList)
                {
                    recipeInfo.ComBoxList.Add(item);
                }
                recipeInfo.ParamKey = "";
            }
        }

        /// <summary>
        /// remove process recipe step
        /// </summary>
        public void RemoveProcessRecipeStep()
        {
            if (RecipeModels.Count == 0)
            {
                MessageBox.Show(LocalizationManager.GetResourceString("There are no more steps to remove."),
                    LocalizationManager.GetResourceString("Remove error"), MessageBoxButton.OK); 
                return; 
            }
            RecipeModel recipeModel = null;
            for (int i = 0; i < RecipeModels.Count; i++)
            {
                if (RecipeModels[i].IsCheck)
                {
                    recipeModel = RecipeModels[i];
                }
            }
            if (recipeModel != null)
            {
                RecipeModels.Remove(recipeModel);
                for (int i = 0; i < RecipeModels.Count; i++)
                {
                    RecipeModels[i].Columes = (i + 1).ToString();
                }
            }
            else
            {
                MessageBox.Show(LocalizationManager.GetResourceString("Please select one step to remove first."),
                    LocalizationManager.GetResourceString("Remove error"), MessageBoxButton.OK);
                return;
            }
        }

        /// <summary>
        /// copy process recipe step
        /// </summary>
        public void CopyProcessRecipeStep()
        {
            cureentIndex = -1;
            for (int i = 0; i < RecipeModels.Count; i++)
            {
                if (RecipeModels[i].IsCheck)
                {
                    cureentIndex = i;
                }
            }
            if (cureentIndex>=0)
            {
                MessageBox.Show(LocalizationManager.GetResourceString("It's copied and you're ready to paste."),
                    LocalizationManager.GetResourceString("Copy complete"));
            }
            else
            {
                MessageBox.Show(LocalizationManager.GetResourceString("Please select one step to copy first."),
                    LocalizationManager.GetResourceString("Step copy"), MessageBoxButton.OK);
            }
        }

        /// <summary>
        /// PASTE process recipe step
        /// </summary>
        public void PasteProcessRecipeStep()
        {
            if (cureentIndex <0)
            {
                MessageBox.Show(LocalizationManager.GetResourceString("Please select one step to copy first."),
                    LocalizationManager.GetResourceString("Step paste"), MessageBoxButton.OK);
                return;
            }
            ObservableCollection<RecipeInfo> recipeList = new ObservableCollection<RecipeInfo>();
            foreach (RecipeInfo item in RecipeModels[cureentIndex].RecipeInfos)
            {
                RecipeInfo recipe = new RecipeInfo();
                recipe.ColueType = item.ColueType;
                recipe.ComBoxList = item.ComBoxList;
                recipe.ContainHardSoft = item.ContainHardSoft;
                recipe.ParamHardToleranceKey = item.ParamHardToleranceKey;
                recipe.ParamKey = item.ParamKey;
                recipe.ParamName = item.ParamName;
                recipe.ParamSoftToleranceKey = item.ParamSoftToleranceKey;
                recipe.RecipeParameter = item.RecipeParameter;
                recipeList.Add(recipe);
            }
            RecipeModel recipeModel = new RecipeModel();
            recipeModel.RecipeInfos = recipeList;
            recipeModel.IsCheck = false;
            recipeModel.Columes =  (RecipeModels.Count + 1).ToString();
            RecipeModels.Add(recipeModel);
        }
         
        private void MoveProcessRecipeStep()
        {
            List<string> steplist = new List<string>();
            foreach (var item in RecipeModels)
            {
                steplist.Add(item.Columes);
            } 
            MoveStepDialog dialog = new MoveStepDialog(steplist);
            dialog.accept += new EventHandler<ParMove>(Win_accept);
            dialog.ShowDialog();

        }

        private void Win_accept(object sender, ParMove parMove)
        { 
            try
            {
                if ((parMove.StepName == "1" && parMove.BeforeOrAfter == -1) || (parMove.StepName == RecipeModels.Count.ToString() && parMove.BeforeOrAfter == 1))
                {
                    return;
                }
                int targetStep = -1;
                if (int.TryParse(parMove.StepName, out targetStep))
                {
                    targetStep = targetStep - 1;
                    RecipeModels.Move(targetStep, targetStep + parMove.BeforeOrAfter);
                    RecipeModels[targetStep + parMove.BeforeOrAfter].Columes = (targetStep + parMove.BeforeOrAfter + 1).ToString();
                    RecipeModels[targetStep].Columes = (targetStep + 1).ToString();
                }
            }
            catch (Exception msg)
            {
                MessageBox.Show(string.Format(LocalizationManager.GetResourceString("Move error: {0}."), msg.Message),
                    LocalizationManager.GetResourceString("Move error"), MessageBoxButton.OK);
            }
        }

        static ExpandoObject DeepCopy(ExpandoObject original)
        {
            var clone = new ExpandoObject();

            var _original = (IDictionary<string, object>)original;
            var _clone = (IDictionary<string, object>)clone;

            foreach (var kvp in _original)
                _clone.Add(kvp.Key, kvp.Value is ExpandoObject ? DeepCopy((ExpandoObject)kvp.Value) : kvp.Value);

            return clone;
        }

      

        private void SaveAsProcessAction()
        {
            #region
            if (RecipeModels.Count == 0)
            {
                MessageBox.Show(LocalizationManager.GetResourceString("Can not save recipe:at least one step"),
                    LocalizationManager.GetResourceString("Recipe save"), MessageBoxButton.OK);
                return;
            }
            OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
            ViewModel.DummyRecipeName = Path.Combine(ViewModel.RecipeLocation, ViewModel.createProcessName);
            ViewModel.DummyProcessLockId = OIClient.Service.LockRecipe(ViewModel.DummyRecipeName);
            ViewModel.DummyProcessRecipe.Processing = new RecipeBlock();
            foreach (RecipeModel viewmodel in RecipeModels)
            {
                string stepName = viewmodel.RecipeInfos[0].ParamKey;
                string[] s = new string[AllColumes.Count];
                for (int i = 0; i < AllColumes.Count; i++)
                {
                    if (AllColumes[i] == "DechuckMode")
                    {
                        s[i] = CBDechuckMode.Text;
                    }
                    else
                    {
                        List<RecipeInfo> recipeInfos = viewmodel.RecipeInfos.ToList();
                        if (AllColumes[i].Contains("_HardTolerance"))
                        {
                            string columName = AllColumes[i].Replace("_HardTolerance", "");
                            RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                            if (recipeInfo != null)
                            {
                                s[i] = recipeInfo.ParamHardToleranceKey;
                            }
                            else
                            {
                                throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                            }
                        }
                        else if (AllColumes[i].Contains("_SoftTolerance"))
                        {
                            string columName = AllColumes[i].Replace("_SoftTolerance", "");
                            RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                            if (recipeInfo != null)
                            {
                                s[i] = recipeInfo.ParamSoftToleranceKey;
                            }
                            else
                            {
                                throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                            }
                        }
                        else
                        {
                            RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == AllColumes[i]).FirstOrDefault();
                            if (recipeInfo != null)
                            {
                                s[i] = recipeInfo.ParamKey;
                            }
                            else
                            {
                                throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                            }
                        }
                    }
                }
                ViewModel.DummyProcessRecipe.Processing.AddProcessStep(stepName, s);
            }
            for (int i = 0; i < AllColumes.Count; i++)
            {
                if (AllColumes[i] == "DechuckMode")
                {
                    ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], CBDechuckMode.Text);
                }
                else
                {
                    List<RecipeInfo> recipeInfos = RecipeModels[0].RecipeInfos.ToList();
                    if (AllColumes[i].Contains("_HardTolerance"))
                    {
                        string columName = AllColumes[i].Replace("_HardTolerance", "");
                        RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                        if (recipeInfo != null)
                        {
                            ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], recipeInfo.ParamHardToleranceKey);
                        }
                        else
                        {
                            throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                        }
                    }
                    else if (AllColumes[i].Contains("_SoftTolerance"))
                    {
                        string columName = AllColumes[i].Replace("_SoftTolerance", "");
                        RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                        if (recipeInfo != null)
                        {
                            ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], recipeInfo.ParamSoftToleranceKey);
                        }
                        else
                        {
                            throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                        }
                    }
                    else
                    {
                        RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == AllColumes[i]).FirstOrDefault();
                        if (recipeInfo != null)
                        {
                            ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], recipeInfo.ParamKey);
                        }
                        else
                        {
                            throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                        }
                    }
                }
            }
            var user = OIClient.Service.CurrentUser;
            if (IsCreate)
            {
                this.ViewModel.DummyProcessRecipe.CreatedBy = user.Name;
                this.ViewModel.DummyProcessRecipe.CreateTime = DateTime.Now.ToString();
                this.ViewModel.CreatedBy = user.Name;
                this.ViewModel.CreateTime = DateTime.Now.ToString();
            }
            else
            {
                this.ViewModel.DummyProcessRecipe.ModifyTime = DateTime.Now.ToString();
                this.ViewModel.ModifyTime = DateTime.Now.ToString();
            }
            this.ViewModel.DummyProcessRecipe.Comments = Remarke.Text;
            this.ViewModel.Comments = Remarke.Text;
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    XmlSerializer serializer = new XmlSerializer(this.ViewModel.DummyProcessRecipe.GetType());
                    serializer.Serialize(ms, this.ViewModel.DummyProcessRecipe);
                    byte[] recipeBytes = ms.ToArray();
                    OIClient.Service.AddRecipe(this.ViewModel.DummyProcessLockId, recipeBytes, ViewModel.DummyRecipeName);
                    OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
                    ViewModel.isRecipeOpened = false;
                    header.Clear();
                    RecipeInfos.Clear();
                    RecipeModels.Clear();
                    AllColumes.Clear();
                    ViewModel.ColumeModels.Clear();
                    this.ViewModel.Comments = "";
                    this.ViewModel.CreatedBy = "";
                    this.ViewModel.CreateTime = "";
                    this.ViewModel.ModifyTime = "";
                    this.ViewModel.RecipeLocation = "";
                    this.ViewModel.PMNumber = "";
                    //this.DG.Columns.Clear();
                    ConcelAuthorityControl();
                    MessageBox.Show(LocalizationManager.GetResourceString("Recipe save success."),
                 LocalizationManager.GetResourceString("Recipe save"), MessageBoxButton.OK);
                }
            }
            catch (Exception ex)
            {
                Log.WriteExceptionCatch("ProcessRecipeScreen", ex);
            }  
            #endregion 
        }
        private void SaveProcessAction()
        {
            #region
            if (RecipeModels.Count == 0)
            {
                MessageBox.Show(LocalizationManager.GetResourceString("Can not save recipe:at least one step"),
                    LocalizationManager.GetResourceString("Recipe save"), MessageBoxButton.OK);
                return;
            }
            ViewModel.DummyProcessRecipe.Processing = new RecipeBlock();
            foreach (RecipeModel viewmodel in RecipeModels)
            {
                string stepName = viewmodel.RecipeInfos[0].ParamKey;
                string[] s = new string[AllColumes.Count];
                for (int i = 0; i < AllColumes.Count; i++)
                { 
                    if (AllColumes[i] == "DechuckMode")
                    {
                       
                        s[i] = CBDechuckMode.Text;
                    }
                    else
                    {
                        List<RecipeInfo> recipeInfos = viewmodel.RecipeInfos.ToList();
                        if (AllColumes[i].Contains("_HardTolerance"))
                        {
                            string columName = AllColumes[i].Replace("_HardTolerance", "");
                            RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                            if (recipeInfo != null)
                            {
                                s[i] = recipeInfo.ParamHardToleranceKey;
                            }
                            else
                            {
                                throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                            }
                        }
                        else if (AllColumes[i].Contains("_SoftTolerance"))
                        {
                            string columName = AllColumes[i].Replace("_SoftTolerance", "");
                            RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                            if (recipeInfo != null)
                            {
                                s[i] = recipeInfo.ParamSoftToleranceKey;
                            }
                            else
                            {
                                throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                            }
                        }
                        else
                        {
                            RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == AllColumes[i]).FirstOrDefault();
                            if (recipeInfo != null)
                            {
                                s[i] = recipeInfo.ParamKey;
                            }
                            else
                            {
                                throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                            }
                        }
                    }
                }
                ViewModel.DummyProcessRecipe.Processing.AddProcessStep(stepName, s);
            }

            for (int i = 0; i < AllColumes.Count; i++)
            {
                if (AllColumes[i] == "DechuckMode")
                {
                    ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], CBDechuckMode.Text);
                }
                else
                {
                    List<RecipeInfo> recipeInfos = RecipeModels[0].RecipeInfos.ToList();
                    if (AllColumes[i].Contains("_HardTolerance"))
                    {
                        string columName = AllColumes[i].Replace("_HardTolerance", "");
                        RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                        if (recipeInfo != null)
                        {
                            ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], recipeInfo.ParamHardToleranceKey);
                        }
                        else
                        {
                            throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                        }
                    }
                    else if (AllColumes[i].Contains("_SoftTolerance"))
                    {
                        string columName = AllColumes[i].Replace("_SoftTolerance", "");
                        RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == columName).FirstOrDefault();
                        if (recipeInfo != null)
                        {
                            ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], recipeInfo.ParamSoftToleranceKey);
                        }
                        else
                        {
                            throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                        }
                    }
                    else
                    {
                        RecipeInfo recipeInfo = recipeInfos.Where(r => r.ParamName == AllColumes[i]).FirstOrDefault();
                        if (recipeInfo != null)
                        {
                            ViewModel.DummyProcessRecipe.Processing.AddParameter(AllColumes[i], recipeInfo.ParamKey);
                        }
                        else
                        {
                            throw new Exception(LocalizationManager.GetResourceString("Data lost!"));
                        }
                    }
                }
            }
            var user = OIClient.Service.CurrentUser;
            if (IsCreate)
            {
                this.ViewModel.DummyProcessRecipe.CreatedBy = user.Name;
                this.ViewModel.DummyProcessRecipe.CreateTime = DateTime.Now.ToString();
                this.ViewModel.CreatedBy = user.Name;
                this.ViewModel.CreateTime = DateTime.Now.ToString();
            }
            else
            {
                this.ViewModel.DummyProcessRecipe.ModifyTime = DateTime.Now.ToString();
                this.ViewModel.ModifyTime = DateTime.Now.ToString();
            }
            this.ViewModel.DummyProcessRecipe.Comments = Remarke.Text;
            this.ViewModel.Comments = Remarke.Text;
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    XmlSerializer serializer = new XmlSerializer(this.ViewModel.DummyProcessRecipe.GetType());
                    serializer.Serialize(ms, this.ViewModel.DummyProcessRecipe);
                    byte[] recipeBytes = ms.ToArray();
                    OIClient.Service.AddRecipe(this.ViewModel.DummyProcessLockId, recipeBytes, ViewModel.DummyRecipeName);
                    OIClient.Service.UnlockRecipe(ViewModel.DummyRecipeName);
                    ViewModel.isRecipeOpened = false;
                    header.Clear();
                    RecipeInfos.Clear();
                    RecipeModels.Clear();
                    AllColumes.Clear();
                    ViewModel.ColumeModels.Clear();
                    this.ViewModel.Comments = "";
                    this.ViewModel.CreatedBy = "";
                    this.ViewModel.CreateTime = "";
                    this.ViewModel.ModifyTime = "";
                    this.ViewModel.RecipeLocation = "";
                    this.ViewModel.PMNumber = "";
                    //this.DG.Columns.Clear();
                    ConcelAuthorityControl();
                    MessageBox.Show(LocalizationManager.GetResourceString("Recipe save success."),
                 LocalizationManager.GetResourceString("Recipe save"), MessageBoxButton.OK);
                }
            }
            catch (Exception ex)
            {
                Log.WriteExceptionCatch("ProcessRecipeScreen", ex);
            }
            #endregion
             
        }

        /// <summary>
        /// Check Number is Int
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public bool CheckInt(string str)
        {
            try
            {
                Convert.ToInt32(str);
                return true;
            }
            catch
            {
                return false;
            }
        }
        private void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9)
            {
                e.Handled = false;
            }
            else if (e.Key >= Key.D0 && e.Key <= Key.D9)
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }

        private void TextBoxDouble_KeyDown(object sender, KeyEventArgs e)
        {
            var txt = sender as TextBox;
            if ((e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) || e.Key == Key.Decimal)
            {
                if (txt != null && (txt.Text.Contains(".") && e.Key == Key.Decimal))
                {
                    e.Handled = true;
                    return;
                }
                e.Handled = false;
            }
            else if (((e.Key >= Key.D0 && e.Key <= Key.D9) || e.Key == Key.OemPeriod) &&
                     e.KeyboardDevice.Modifiers != ModifierKeys.Shift)
            {
                if (txt != null && (txt.Text.Contains(".") && e.Key == Key.OemPeriod))
                {
                    e.Handled = true;
                    return;
                }
                e.Handled = false;
            }
            else if (e.Key == Key.Enter)
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
                return;
            }
        }

        private void NumberText_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex re = new Regex("[^0-9]");
            if (e.Text == "'")
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = CheckInt(e.Text);
            }
        }

        private void NumberdoubleText_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex re = new Regex("[^0-9.]");
            if (e.Text == "'")
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = re.IsMatch(e.Text);
            }
        }
        private void StringText_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox.Tag != null)
            {
                if (textBox.Tag.ToString().Contains("*") && textBox.Text != "'")
                {
                    int MaxLength = 0;
                    try
                    {
                        bool isnumber = int.TryParse(textBox.Tag.ToString().Split('*')[1], out MaxLength);
                        if (!isnumber)
                            MaxLength = 0;
                        if (textBox.Text.Length >= MaxLength)
                        {
                            e.Handled = true;
                        }
                    }
                    catch (Exception)
                    {

                        throw;
                    }

                }
            }
        }
        private void TextBox_TextChanged(object sender, EventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox.ToolTip != null)
            {
                if (textBox.ToolTip.ToString().Contains("—") && textBox.Text != "'")
                {
                    try
                    {
                        if (Convert.ToDouble(textBox.Text) > Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[1]))
                        {
                            textBox.Text = textBox.Tag.ToString().Split('*')[2];
                        }
                    }
                    catch (Exception)
                    {
                        textBox.Text = textBox.Tag.ToString().Split('*')[2];
                    }
                }
                else
                {
                    textBox.ToolTip = textBox.Text;
                }
            }
            else
            {
                textBox.ToolTip = textBox.Text;
            }
        }
        private void TextBoxstring_TextChanged(object sender, EventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox.Tag != null)
            {
                if (textBox.Tag.ToString().Contains("*") && textBox.Text != "'")
                {
                    int MaxLength = 0;
                    try
                    {
                        bool isnumber = int.TryParse(textBox.Tag.ToString().Split('*')[1], out MaxLength);
                        if (!isnumber)
                            MaxLength = 0;
                        if (textBox.Text.Length >= MaxLength)
                        {
                            textBox.Text = textBox.Text.Substring(0, MaxLength); ;
                        }
                    }
                    catch (Exception)
                    {
                        textBox.Text = "";

                    }
                }
            }
            textBox.ToolTip = textBox.Text;
        }
        private void TextBoxDouble_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox.ToolTip != null)
            {
                if (textBox.ToolTip.ToString().Contains("—") && textBox.Text != "'")
                {
                    try
                    {
                        if (textBox != null)
                        {
                            var change = new TextChange[e.Changes.Count];
                            e.Changes.CopyTo(change, 0);

                            int offset = change[0].Offset;
                            if (change[0].AddedLength > 0)
                            {
                                double num;
                                if (!Double.TryParse(textBox.Text, out num))
                                {
                                    textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength);
                                    textBox.Select(offset, 0);
                                }
                            }
                            if (textBox.Text.StartsWith("."))
                            {
                                textBox.Text = textBox.Text.Replace(".", "0.");
                            }
                            else if (textBox.Text.StartsWith("0") && textBox.Text.Length > 1)
                            {
                                if (textBox.Text.Substring(1, 1) != ".")
                                {
                                    textBox.Text = textBox.Text.Substring(1, textBox.Text.Length - 1);
                                }
                            }
                            if (textBox.Text.Contains("."))
                            {
                                string head = textBox.Text.Split('.')[0];
                                string behind = textBox.Text.Split('.')[1];
                                string index = textBox.Tag.ToString().Split('*')[1];
                                if (index == "1")
                                {
                                    textBox.Text = head;
                                }
                                else if (textBox.Text.Contains("."))
                                {
                                    int vlength = index.Split('.')[1].Length;
                                    if (behind.Length > vlength)
                                    {
                                        behind = behind.Substring(0, vlength);
                                        textBox.Text = head + "." + behind;
                                    }
                                    if (ToDouble(textBox.Text) < Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[0]) || ToDouble(textBox.Text) > Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[1]))
                                    {
                                        textBox.Text = textBox.Tag.ToString().Split('*')[2];
                                    }
                                }
                            }
                            else
                            {
                                string index = textBox.Tag.ToString().Split('*')[1];
                                if (ToDouble(textBox.Text) < Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[0]) || ToDouble(textBox.Text) > Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[1]))
                                {
                                    textBox.Text = textBox.Tag.ToString().Split('*')[2];
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        textBox.Text = textBox.Tag.ToString().Split('*')[2];
                    }
                }
                else
                {
                    textBox.ToolTip = textBox.Text;
                }
            }
            else
            {
                textBox.ToolTip = textBox.Text;
            }
            //var textBox = sender as TextBox;
            //if (textBox != null)
            //{
            //    var change = new TextChange[e.Changes.Count];
            //    e.Changes.CopyTo(change, 0);

            //    int offset = change[0].Offset;
            //    if (change[0].AddedLength > 0)
            //    {
            //        double num;
            //        if (!Double.TryParse(textBox.Text, out num))
            //        {
            //            textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength);
            //            textBox.Select(offset, 0);
            //        }
            //    }
            //    if (textBox.Text.StartsWith("."))
            //    {
            //        textBox.Text = textBox.Text.Replace(".", "0.");
            //    }
            //    else if (textBox.Text.StartsWith("0")&& textBox.Text.Length>1)
            //    {
            //        if (textBox.Text.Substring(1, 1) != ".")
            //        {
            //            textBox.Text = textBox.Text.Substring(1, textBox.Text.Length - 1);
            //        }
            //    }
            //    if (textBox.Text.Contains("."))
            //    {
            //        string head = textBox.Text.Split('.')[0];
            //        string behind = textBox.Text.Split('.')[1];
            //        string index = textBox.Tag.ToString().Split('*')[1];
            //        if (index == "1")
            //        {
            //            textBox.Text = head;
            //        }
            //        else if (textBox.Text.Contains("."))
            //        {
            //            int vlength = index.Split('.')[1].Length;
            //            if (behind.Length > vlength)
            //            {
            //                behind = behind.Substring(0, vlength);
            //                textBox.Text = head+"."+ behind;
            //            }
            //            if (ToDouble(textBox.Text) < Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[0]) || ToDouble(textBox.Text) > Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[1]))
            //            {
            //                textBox.Text = textBox.Tag.ToString().Split('*')[2];
            //            }
            //        }
            //    }
            //    else
            //    {
            //        string index = textBox.Tag.ToString().Split('*')[1];
            //        if (ToDouble(textBox.Text) < Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[0]) || ToDouble(textBox.Text) > Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[1]))
            //        {
            //            textBox.Text = textBox.Tag.ToString().Split('*')[2];
            //        }
            //    }
            //}
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox.ToolTip != null)
            {
                if (textBox.ToolTip.ToString().Contains("—"))
                {
                    try
                    {
                        if (Convert.ToDouble(textBox.Text) < Convert.ToDouble(textBox.ToolTip.ToString().Split('—')[0]))
                        {
                            textBox.Text = textBox.Tag.ToString().Split('*')[2];
                        }
                        else
                        {
                            textBox.Text = Double.Parse(textBox.Text).ToString();
                            if (textBox.Text.Contains("."))
                                textBox.Text = Convert.ToDecimal(textBox.Text).ToString("0.00");
                        }
                    }
                    catch (Exception)
                    {
                        textBox.Text = textBox.Tag.ToString().Split('*')[2];
                    }
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strText"></param>
        /// <returns></returns>
        public double ToDouble(string strText)
        {
            double result;
            bool success = double.TryParse(strText, out result);
            if (success)
                return result;
            else
                return 0;
        }
        /// <summary>
        /// Object Is Number
        /// </summary>
        /// <param name="sNum"></param>
        /// <returns></returns>
        public bool IsNumber(object sNum)
        {
            long num;   //临时变量
            if (sNum == null)
            {
                return false;   //如果传入的值为NULL,返回False
            }
            if (long.TryParse(sNum.ToString(), out num))    //尝试转换传入的值
                return true;    //成功返回True
            else
                return false;   //失败返回False
        }

        /// <summary>
        /// Return ColumeModel
        /// </summary>
        /// <returns></returns>
        public DataGridTemplateColumn GetColume(ColumeModel item)
        {
            var stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));
            stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
            var textBox = new FrameworkElementFactory(typeof(TextBox));
            textBox.SetBinding(TextBox.TextProperty, new Binding(item.ColumeName));

            Style style = new Style();
            style.TargetType = typeof(TextBox);
            DataTrigger dataTrigger = new DataTrigger();
            dataTrigger.Binding = new Binding
            {
                Path = new PropertyPath("Text"),
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                Mode = BindingMode.TwoWay,
                RelativeSource = RelativeSource.Self,
            };
            dataTrigger.Value = "'";
            dataTrigger.Setters.Add(new Setter(FrameworkElement.VisibilityProperty, Visibility.Hidden));
            dataTrigger.Setters.Add(new Setter(FrameworkElement.WidthProperty, (double)1));
            style.Triggers.Add(dataTrigger);
            textBox.SetValue(StyleProperty, style);
            textBox.SetValue(InputMethod.IsInputMethodEnabledProperty, false); //can not wreate chaniese
            textBox.SetBinding(TextBox.TextProperty,
                new Binding()
                {
                    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                    Path = new PropertyPath(item.ColumeName),
                }
                );
            if (item.ColumeName != "Parameter" && item.ColumeName != "Step Name")
            {

                if (item.recipeParameter.ParamType == ParamType.INT)
                {
                    textBox.SetValue(ToolTipProperty, item.recipeParameter.Min + "—" + item.recipeParameter.Max);
                    textBox.SetValue(TagProperty, "int" + "*" + item.recipeParameter.Max + "*" + item.recipeParameter.DefaultValue);
                    //textBox.AddHandler(TextBox.PreviewTextInputEvent, new TextCompositionEventHandler(NumberText_PreviewTextInput), true);
                    textBox.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBox_TextChanged), true);
                    textBox.AddHandler(TextBox.LostFocusEvent, new RoutedEventHandler(TextBox_LostFocus));
                    textBox.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(TextBox_KeyDown));
                }
                else if (item.recipeParameter.ParamType == ParamType.DOUBLE)
                {
                    textBox.SetValue(ToolTipProperty, item.recipeParameter.Min + "—" + item.recipeParameter.Max);
                    textBox.SetValue(TagProperty, "double" + "*" + item.recipeParameter.Accuracy + "*" + item.recipeParameter.DefaultValue);
                    textBox.AddHandler(TextBox.PreviewTextInputEvent, new TextCompositionEventHandler(NumberdoubleText_PreviewTextInput), true);
                    textBox.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBoxDouble_TextChanged), true); //textBox.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBoxDouble_TextChanged), true);
                    textBox.AddHandler(TextBox.LostFocusEvent, new RoutedEventHandler(TextBox_LostFocus));
                    textBox.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(TextBoxDouble_KeyDown));
                }
                else
                {
                    textBox.SetValue(ToolTipProperty, textBox.Text);
                    textBox.SetValue(TagProperty, "string" + "*" + item.recipeParameter.MaxLength + "*" + item.recipeParameter.DefaultValue);
                    textBox.AddHandler(TextBox.PreviewTextInputEvent, new TextCompositionEventHandler(StringText_PreviewTextInput), true);
                    textBox.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBoxstring_TextChanged), true);
                    textBox.AddHandler(TextBox.LostFocusEvent, new RoutedEventHandler(TextBox_LostFocus));
                }

            }
            else
            {
                textBox.SetValue(ToolTipProperty, textBox.Text);
                textBox.SetValue(TagProperty, "string" + "*" + "50" + "*" + "");
                textBox.AddHandler(TextBox.PreviewTextInputEvent, new TextCompositionEventHandler(StringText_PreviewTextInput), true);
                textBox.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBoxstring_TextChanged), true);
                textBox.AddHandler(TextBox.LostFocusEvent, new RoutedEventHandler(TextBox_LostFocus));
            }
            textBox.SetValue(BorderBrushProperty, null);
            textBox.SetValue(WidthProperty, (double)68);
            stackPanelFactory.AppendChild(textBox);

            var dataTemplate = new DataTemplate
            {
                VisualTree = stackPanelFactory
            };
            var templateColumn = new DataGridTemplateColumn
            {
                Header = item.ColumeName,
                CellTemplate = dataTemplate
            };
            templateColumn.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
            templateColumn.SetValue(VerticalAlignmentProperty, VerticalAlignment.Stretch);
            return templateColumn;
        }

        private void DG_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            //e.Handled = true;
        }


        private void DGCombox_GotFocus(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
        }


        private void DGCombox_Drop(object sender, RoutedEventArgs e)
        {
            ComboBox cb = sender as ComboBox;
            cb.IsDropDownOpen = false;
            cb.ItemsSource = null;
            e.Handled = true;
        }

        private void OESButton_Click(object sender, RoutedEventArgs e)
        {


        }


        #endregion

        private void SV2_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {

            ScrollViewer sv = e.OriginalSource as ScrollViewer;

            if (sv != null)
            {
                if (!(e.VerticalChange == 0))
                {
                    scrow.ScrollToVerticalOffset(sv.VerticalOffset);
                }

            }
        }

        private void Setpoint_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            ScrollViewer sv = e.OriginalSource as ScrollViewer;

            if (sv != null)
            {
                if (!(e.VerticalChange == 0))
                {
                    scrowsetpoint.ScrollToVerticalOffset(sv.VerticalOffset);
                }

            }
       
        }
        private void listview_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            e.Handled = true;
        }

        ScrollViewer scrollViewer = null;
        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (RecipeTabControl.SelectedIndex == 1)
            {
                scrollViewer = ToleranceRecipeView.Template.FindName("TScroll", ToleranceRecipeView) as ScrollViewer;
            }
            else if (RecipeTabControl.SelectedIndex == 0)
            {
                scrollViewer = RecipeView.Template.FindName("SScroll", RecipeView) as ScrollViewer;
            }
        }

        private void scrow_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (RecipeTabControl.SelectedIndex==1)
            {
                if (scrollViewer != null)
                {
                    if (sender is ScrollViewer sc)
                    {
                        if (sc.VerticalOffset != scrollViewer.VerticalOffset)
                        {
                            sc.ScrollToVerticalOffset(scrollViewer.VerticalOffset);
                        }
                    }
                }
            }
        }

        private void scrowsetpoint_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (RecipeTabControl.SelectedIndex==0)
            {
                if (scrollViewer != null)
                {
                    if (sender is ScrollViewer sc)
                    {
                        if (sc.VerticalOffset != scrollViewer.VerticalOffset)
                        {
                            sc.ScrollToVerticalOffset(scrollViewer.VerticalOffset);
                        }
                    }
                }
            }
        }
    }
    public class RecipeModel : NotifyPropertyBase
{
    private string columes;
    /// <summary>
    /// 
    /// </summary>
    public string Columes
    {
        get { return columes; }
        set
        {
            columes = value;
            OnPropertyChanged("Columes");
        }
    }

    private bool isCheck;
    /// <summary>
    /// 
    /// </summary>
    public bool IsCheck
    {
        get { return isCheck; }
        set
        {
            isCheck = value;
            OnPropertyChanged("IsCheck");
        }
    }

    private ObservableCollection<RecipeInfo> recipeInfos;
    /// <summary>
    /// 
    /// </summary>
    public ObservableCollection<RecipeInfo> RecipeInfos
    {
        get { return recipeInfos; }
        set
        {
            recipeInfos = value;
            OnPropertyChanged("RecipeInfos");
        }
    }
}

/// <summary>
/// 
/// </summary>
[Serializable]
public class RecipeInfo : NotifyPropertyBase
{
    private bool containHardSoft;
    /// <summary>
    /// 
    /// </summary>
    public bool ContainHardSoft
    {
        get { return containHardSoft; }
        set
        {
            containHardSoft = value;
            OnPropertyChanged("ContainHardSoft");
        }
    }


    private ObservableCollection<string> comBoxList;
    /// <summary>
    /// 
    /// </summary>
    public ObservableCollection<string> ComBoxList
    {
        get { return comBoxList; }
        set
        {
            comBoxList = value;
            OnPropertyChanged("ComBoxList");
        }
    }

    private string paramName;
    /// <summary>
    /// 
    /// </summary>
    public string ParamName
    {
        get { return paramName; }
        set
        {
            paramName = value;
            OnPropertyChanged("ParamName");
        }
    }

    private string paramKey;
    /// <summary>
    /// 
    /// </summary>
    public string ParamKey
    {
        get { return paramKey; }
        set
        {
            paramKey = value;
            OnPropertyChanged("ParamKey");
        }
    }

    private string paramSoftToleranceKey;
    /// <summary>
    /// 
    /// </summary>
    public string ParamSoftToleranceKey
    {
        get { return paramSoftToleranceKey; }
        set
        {
            paramSoftToleranceKey = value;
            OnPropertyChanged("ParamSoftToleranceKey");
        }
    }


    private string paramHardToleranceKey;
    /// <summary>
    /// 
    /// </summary>
    public string ParamHardToleranceKey
    {
        get { return paramHardToleranceKey; }
        set
        {
            paramHardToleranceKey = value;
            OnPropertyChanged("ParamHardToleranceKey");
        }
    }


    private string colueType;
    /// <summary>
    /// 
    /// </summary>
    public string ColueType
    {
        get { return colueType; }
        set
        {
            colueType = value;
            OnPropertyChanged("ColueType");
        }
    }


    private RecipeParameter recipeParameter;
    /// <summary>
    /// 
    /// </summary>
    public RecipeParameter RecipeParameter
    {
        get { return recipeParameter; }
        set
        {
            recipeParameter = value;
            OnPropertyChanged("RecipeParameter");
        }
    }

}


/// <summary>
/// 左侧表头数据集合
/// </summary>
[Serializable]
public class GridHeaderClass : NotifyPropertyBase
{
    private string gridHeader;
    /// <summary>
    /// view property Name of list
    /// </summary>
    public string GridHeader
    {
        get { return gridHeader; }
        set
        {
            gridHeader = value;
            OnPropertyChanged("GridHeader");
        }
    }

    private int index;
    /// <summary>
    /// view property Name of list
    /// </summary>
    public int Index
    {
        get { return index; }
        set
        {
            index = value;
            OnPropertyChanged("Index");
        }
    }

}

/// <summary>
/// TreeView PropertyChanged
/// </summary>
[Serializable]
public class NotifyPropertyBase : INotifyPropertyChanged
{
    /// <summary>
    /// The inrerface from INotifyPropertyChanged
    /// </summary>
    /// <param name="propertyName"></param>
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    /// <summary>
    /// PropertyChanged ChangedEventHandler
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;
}
举报

相关推荐

0 条评论