using Aitex.Common.Util; using Aitex.Core.Account; using Aitex.Core.RT.ConfigCenter; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.DataCollection; using Aitex.Core.RT.DBCore; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Core.WCF; using Aitex.Sorter.Common; using athosRT.Devices; using athosRT.FSM; using athosRT.Modules.LPs; using athosRT.Modules.Robot; using athosRT.tool; using Caliburn.Micro; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SCCore; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.Core.IoProviders; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using athosRT.Devices.IODevices; using System.Xml; using System.Xml.Linq; using static MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase.RobotBaseDevice; using MECF.Framework.Common.IOCore; using Aitex.Core.RT.IOCore; using System.Net; using athosRT.Modules; using System.Windows.Threading; using Common.WcfService; using WcfServiceManager = Common.WcfServiceManager; using OperationManager = Common.OP.OperationManager; using Common.WcfService.Efem; using Aitex.Core.Common; using OP = Common.OP.OP; using MECF.Framework.Common.DataCenter; using DataManager = Common.DataCenter.DataManager; using DATA = Common.DataCenter.DATA; using QueryDataService = Common.DataCenter.QueryDataService; using athosRT.Modules.EFEMs; using static athosRT.Modules.EFEMs.EfemEntity; using athosRT.Devices.LP; using System.Text.RegularExpressions; using athosRT.Devices.FLP; using Aitex.Core.RT.Log; namespace athosRT { public class MainWindowViewModel : PropertyChangedBase { private TreeChildren _sc; public TreeChildren SCTree { get { return _sc; } set { _sc = value; NotifyOfPropertyChange(() => SCTree); } } private List _gridDatas; public List GridDatas { get { return _gridDatas; } set { _gridDatas = value; NotifyOfPropertyChange(() => GridDatas); } } public ICommand OnLoad { get; set; } public List RTMsg { get; set; } private string _selectedMsg; public string SelectedMsg { get { return _selectedMsg; } set { _selectedMsg = value; NotifyOfPropertyChange(() => RTMsg); } } public DispatcherTimer _dp; public List LPSET { get; set; } public List LPGET { get; set; } public List LPMOV { get; set; } private string _flipperstate; public string FlipperState { get { return _flipperstate; } set { _flipperstate = value; NotifyOfPropertyChange(() => FlipperState); } } private string lpsetcommand; private string lpgetcommand; private string lpmovcommand; private string setparam; public string LPSetCommand { get{ return lpsetcommand; } set{ lpsetcommand = value; NotifyOfPropertyChange(()=> LPSetCommand); } } public string LPGetCommand { get{ return lpgetcommand; } set{ lpgetcommand = value; NotifyOfPropertyChange(()=> LPGetCommand); } } public string LPMovCommand { get{ return lpmovcommand; } set{ lpmovcommand = value; NotifyOfPropertyChange(()=> LPMovCommand); } } public string SetParam { get { return setparam; } set { setparam = value;NotifyOfPropertyChange(()=> SetParam); } } private HirataLoadPort lp; public MainWindowViewModel() { Singleton.Instance.Initialize();//框架下OP的初始化 Singleton.Instance.Initialize();//框架下Data的初始化 WcfServiceManager.Instance.Initialize(new Type[] {//框架下WCF的初始化 typeof(SomebodyService),typeof(EfemService),typeof(QueryDataService) }); Trace.WriteLine(ModuleName.LP1.ToString()); OnLoad = new CommandBase(Load); LogObject.Info("RT", "--------------------------------------------------"); SCTree = new TreeChildren(); string xmlFileName = PathManager.GetCfgDir() + "Efem.sccfg"; Singleton.Instance.Initialize(xmlFileName); GetSCTreeStatus();//厘清SC树的构造 并赋予变量SCTree GridDatas = new List() { }; RTMsg = getmsgitems(); SelectedMsg = RTMsg.Count > 0 ? RTMsg[0].ToString() : ""; //设备的初始化需要在构造中进行 否则页面无法正常运行 InitCommonModules(); GetIOCard(); //Debug(); } private void Debug() { LPSET = new List() { "RSET", "RTRY", "STPP", "PASE", "ABOT", "RESM", "TYP1", "TYP2", "TYP3", "TYP4", "TYP5", "MAPP", "MAP1", "MAP2", "POSO", }; LPGET = new List() { "STAS","STA1","STA2","MDAT", "MAPR","VERN","MAPP","MAP1", "MAP2","POSO","POSD","MDAH", "MDAP","MDTC","MDHS","MDPS","LEST",}; LPMOV = new List() { "ORGN","ABGN","FPLD","FPML", "FDOC","FDLD","FDML","FCLD", "FCML","FPUL","FPMU","FVOF", "FVUL","FUDC","FUMD","MAPP", "RMAP","Z_MP",}; LPSetCommand = LPSET[0]; LPGetCommand = LPGET[0]; LPMovCommand = LPMOV[0]; SetParam = ""; //lp = lp = new HirataLoadPort("LP3", "LP3", "LoadPort", (RobotBaseDevice)null); } public void SendSet() { string sendcommand = "SET:"+LPSetCommand; if (SetParam == "") { sendcommand += ";"; } else { sendcommand += $"/{SetParam};"; } lp.SendMessage(sendcommand); } public void SendGet() { string sendcommand = "GET:"+LPGetCommand+";"; Trace.WriteLine(sendcommand); lp.SendMessage(sendcommand); } public void SendMov() { string sendcommand = "MOV:"+LPMovCommand+";"; Trace.WriteLine(sendcommand); lp.SendMessage(sendcommand); } #region flipper 调试代码 不标准后续删除 //public void FlipperHome() { Singleton.Instance._flipper.Check(1,out _); } //public void FlipperTurn() { Singleton.Instance._flipper.PostMsg(2); } //public void FlipperClamp() { Singleton.Instance._flipper.PostMsg(3, !Singleton.Instance._flipper.ClampOpen); } #endregion private void DataTimer_Tick(object sender, EventArgs e) { //RtState state; //if (Enum.TryParse(Singleton.Instance.GetFsmState, out state)) //{ // Trace.WriteLine("-------------------当前RT状态:" + (RtState)state + "-------------------"); //} //Trace.WriteLine("-------------------当前RT Running:" + Singleton.Instance.IsRunning + "-------------------"); //if (Enum.TryParse(Singleton.Instance.GetFsmState, out state)) //{ // Trace.WriteLine("-------------------当前EFEM状态:" + (ServerState)state + "-------------------"); //} //Trace.WriteLine("-------------------当前Robot状态:" + DEVICE.GetDevice("Robot").RobotState + "-------------------"); ////if (_isPresent && _isPlaced && _isLoaded && IsReady() && _isMapped) //LoadPortBaseDevice lp1= DEVICE.GetDevice("LP1"); //Trace.WriteLine($"----当前LP1状态:Loaded:{lp1.IsLoaded} Ready:{lp1.IsReady()} Mapped:{lp1.IsMapped} DockState:{lp1.DockState}----"); //LoadPortBaseDevice lp2 = DEVICE.GetDevice("LP2"); //Trace.WriteLine($"----当前LP2状态:Loaded:{lp2.IsLoaded} Ready:{lp2.IsReady()} Mapped:{lp2.IsMapped} DockState:{lp2.DockState}----"); GetIOCard(); //flipper状态 FlipperState = Singleton.Instance.GetFlipper().State.ToString(); } private void Load() { Singleton.Instance.Initialize();//RT控制初始化 Singleton.Instance.SetEfemData(); Singleton.Instance.Initialize(); DATA.Subscribe($"DIItemList", () => DiItemList);//DI数据传递 DATA.Subscribe($"DOItemList", () => DoItemList);//DO数据传递 DATA.Subscribe("GetLogList",()=> LogObject.GetLogList()); //====lp debug===== //lp = new HirataLoadPort("", "LP3", "LoadPort", (RobotBaseDevice)null); //lp.SendMessage("MOV:ORGN;"); //================= _dp = new DispatcherTimer(); _dp.Tick += new EventHandler(DataTimer_Tick); _dp.Interval = TimeSpan.FromSeconds(2); _dp.Start(); } public void ChangeState() { RouteManager1.MSG willsend; if (Enum.TryParse(SelectedMsg, out willsend)) { Trace.WriteLine("发送指令"+willsend); switch (willsend) { case RouteManager1.MSG.MapWafer: Singleton.Instance.CheckToPostMsg((RouteManager1.MSG)willsend,"LP1"); break; case RouteManager1.MSG.Pick: Singleton.Instance.CheckToPostMsg((RouteManager1.MSG)willsend, "CoolingBuffer1", 0, 0); break; case RouteManager1.MSG.Place: Singleton.Instance.CheckToPostMsg((RouteManager1.MSG)willsend, "CoolingBuffer1", 0, 0); break; default: Singleton.Instance.CheckToPostMsg((RouteManager1.MSG)willsend); break; } } } private List getmsgitems() { List msgs = new List(); foreach (var i in Enum.GetValues(typeof(RouteManager1.MSG))) { msgs.Add(i.ToString()); } return msgs; } public void _comfirmChange(object item) { GridData SelectData = (GridData)item; //Trace.WriteLine("修改前的值是" + SelectData.CurrentValue); //告知sc修改SetItemValue switch (SelectData.Type) { case "Integer": if (int.TryParse(SelectData.Setpoint, out _)) { SCConfigItem _item = SC.GetConfigItem(SelectData.Header + "." + SelectData.Name); SC.SetItemValue(SelectData.Header + "." + SelectData.Name, SelectData.Setpoint); SC.SetItemValueFromString(SelectData.Header + "." + SelectData.Name, SelectData.Setpoint); _item = SC.GetConfigItem(SelectData.Header + "." + SelectData.Name); } break; case "Bool": if (bool.TryParse(SelectData.Setpoint, out _)) { SC.SetItemValue(SelectData.Header + "." + SelectData.Name, SelectData.Setpoint); SC.SetItemValue(SelectData.Header + "." + SelectData.Name, SelectData.Setpoint); } break; default: SC.SetItemValue(SelectData.Header + "." + SelectData.Name, SelectData.Setpoint); SC.SetItemValue(SelectData.Header + "." + SelectData.Name, SelectData.Setpoint); break; } for (int i = 0; i < GridDatas.Count; i++) { if (SC.GetStringValue(SelectData.Header + "." + SelectData.Name) == SelectData.Setpoint && GridDatas[i].Header == SelectData.Header && GridDatas[i].Name == SelectData.Name) { GridDatas[i].CurrentValue = SelectData.Setpoint; } } } public void _showttems(object Items) { List lst = (List)Items;//获取所有配置项 List SelectDatas = new List(); foreach (var item in lst) { SelectDatas.Add( new GridData() { Header = item.Path, Description = item.Description, Unint = item.Unit, Min = item.Min, Max = item.Max, CurrentValue = SC.GetConfigItem(item.Path+"." + item.Name).Value.ToString(), Comfirm = new CommandBase(_comfirmChange), Setpoint = SC.GetConfigItem(item.Path + "." + item.Name).Value.ToString(), Name = item.Name, Type = item.Type, }); } GridDatas = SelectDatas; } //设备文件解析和初始化的函数 private void InitCommonModules() { Singleton.Instance.Initialize(PathManager.GetCfgDir() + "DeviceDefine.xml"); string xmlConfigFile = PathManager.GetCfgDir() + "IoProviderConfig.xml"; int? nullable = Singleton.Instance.GetValue("IoCardQuantity"); Dictionary> ioMappingPathFile; if (nullable.HasValue) { switch (nullable.GetValueOrDefault()) { case 1: ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCardNew.xml" } } }, { "System.Super", new Dictionary() { { 256, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\\\_diDefineSuper.xml" }, { 512, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\\\_doDefineSuper.xml" }, { 1001, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\\\_aiDefineSuper.xml" }, { 2001, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\\\_aoDefineSuper.xml" } } } }; goto label_10; case 2: ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCardNew.xml" } } }, { "System.dio001", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard2.xml" } } } }; goto label_10; case 3: ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCardNew.xml" } } }, { "System.dio001", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard2.xml" } } }, { "System.dio002", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard3.xml" } } } }; goto label_10; case 4: ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCardNew.xml" } } }, { "System.dio001", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard2.xml" } } }, { "System.dio002", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard3.xml" } } }, { "System.dio003", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard4.xml" } } } }; goto label_10; case 5: ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCardNew.xml" } } }, { "System.dio001", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard2.xml" } } }, { "System.dio002", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard3.xml" } } }, { "System.dio003", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard4.xml" } } }, { "System.dio004", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard5.xml" } } } }; goto label_10; case 6: ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCardNew.xml" } } }, { "System.dio001", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard2.xml" } } }, { "System.dio002", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard3.xml" } } }, { "System.dio003", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard4.xml" } } }, { "System.dio004", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard5.xml" } } }, { "System.dio005", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard6.xml" } } } }; goto label_10; case 7: ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCardNew.xml" } } }, { "System.dio001", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard2.xml" } } }, { "System.dio002", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard3.xml" } } }, { "System.dio003", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard4.xml" } } }, { "System.dio004", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard5.xml" } } }, { "System.dio005", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard6.xml" } } }, { "System.dio006", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineCard7.xml" } } } }; goto label_10; } } ioMappingPathFile = new Dictionary>() { { "System.dio000", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefine.xml" } } } }; label_10: if (Singleton.Instance.GetValue("MotionAxisInstalled").GetValueOrDefault()) ioMappingPathFile.Add("System.MotionAxis", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineMotionAxis.xml" } }); if (Singleton.Instance.GetValue("PLCIoInstalled").GetValueOrDefault()) ioMappingPathFile.Add("System.MainPlc", new Dictionary() { { 0, PathManager.GetCfgDir() + SC.GetStringValue("System.DeviceType") + "\\_ioDefineMainPlc.xml" } }); foreach (var keyValuePair in ioMappingPathFile) { //LOG.Write($"Key:{keyValuePair.Key} -- Value:{keyValuePair.Value}"); } Singleton.Instance.Initialize(xmlConfigFile, ioMappingPathFile); Singleton.Instance.Initialize();//框架下WaferManager的初始化 Singleton.Instance.Initialize(); Singleton.Instance.Initialize();//设备初始化 //Trace.WriteLine(PathManager.GetCfgDir() + "DeviceModel.xml"); Singleton.Instance.Initialize(PathManager.GetCfgDir() + "DeviceModelNew.xml", "EFEM"); } //验证设备状态的点击事件 不是很重要 后期移除 public void GetSomeDevice() { //开一个服务用于数据的订阅 //WaferInfo[] waferInfos = WaferManager.Instance.GetWafers(ModuleName.LP1); //Trace.WriteLine(waferInfos.Length); LoadPortBaseDevice LP = DEVICE.GetDevice("LP2"); if (LP == null) { Trace.WriteLine("暂无此设备"); } else { Trace.WriteLine("LP设备获取完毕"); } RobotBaseDevice Robot = DEVICE.GetDevice("Robot"); if (Robot == null) { Trace.WriteLine("暂无此设备"); } else { Trace.WriteLine("Robot设备获取完毕"); } LoadLockDevice LL1 = DEVICE.GetDevice("LL1"); if (LL1 == null) { Trace.WriteLine("暂无此设备"); } else { Trace.WriteLine("LL1设备获取完毕"); } IoCoolingBuffer coolingBuffer1 = DEVICE.GetDevice("buffer"); if (coolingBuffer1 == null) { Trace.WriteLine("暂无此设备"); } else { Trace.WriteLine("coolingBuffer1设备获取完毕"); } } public void StartCycle() { Singleton.Instance.PostMsg(RouteManager1.MSG.StartCycle); } /// /// 初始化一些数据 对获取的数据进行一个刷新 /// private void GetIOCard() { DiItemList = new ObservableCollection() { }; DoItemList = new ObservableCollection() { }; AiItemList = new ObservableCollection() { }; AoItemList = new ObservableCollection() { }; //对IO数据进行获取 List dilist = IO.GetDiList("System.dio000"); foreach (DIAccessor diAccessor in dilist) DiItemList.Add(new NotifiableIoItem() { Name = diAccessor.Name, Index = diAccessor.Index, Description = diAccessor.Description, BoolValue = diAccessor.Value, Address = diAccessor.Addr }); List dolist = IO.GetDoList("System.dio000"); foreach (DOAccessor doAccessor in dolist) { DoItemList.Add(new NotifiableIoItem() { Name = doAccessor.Name, Index = doAccessor.Index, Description = doAccessor.Description, BoolValue = doAccessor.Value, Address = doAccessor.Addr }); } //Trace.WriteLine(DiItemList.Count.ToString() + "" + DoItemList.Count.ToString()); } //-------------涉及到IO数据的一些变量 要注意数据变化------------ private ObservableCollection _diItemList; private ObservableCollection _doItemList; public ObservableCollection DiItemList { get { return _diItemList; } set { _diItemList = value; NotifyOfPropertyChange(() => DiItemList); } } public ObservableCollection DoItemList { get { return _doItemList; } set { _doItemList = value; NotifyOfPropertyChange(() => DoItemList); } } public ObservableCollection AiItemList { get; set; } public ObservableCollection AoItemList { get; set; } //构建sc树的逻辑 public void GetSCTreeStatus() { List SClist = SC.GetItemList(); Dictionary scdic = new Dictionary(); for (int i = 0; i < SClist.Count; i++) { TreeChildren tc1;//大类 string headerName = SClist[i].Path.Split('.')[0]; if (!scdic.ContainsKey(headerName)) { //没有先new //Trace.WriteLine("添加"+ headerName); tc1 = new TreeChildren(headerName); tc1.ShowItems = new CommandBase(_showttems); scdic.Add(headerName, tc1); } else { //有了就加入 scdic.TryGetValue(headerName, out tc1); } //----分割---- if (SClist[i].Path.Contains(".")) { //有点 加到子目录 bool flag = false; TreeChildren tc2 = new TreeChildren(); foreach (var itlist in tc1.Children) { if (itlist.Name == SClist[i].Path.Split('.')[1]) { tc2 = itlist; flag = true; break; } } if (flag) { //说明有这个子类直接加到Items中 tc2.Items.Add(SClist[i]); } else { //没有子类 新建一下 tc2 = new TreeChildren(SClist[i].Path.Split('.')[1]);//小类 tc2.Items.Add(SClist[i]); tc2.ShowItems = new CommandBase(_showttems); tc1.Children.Add(tc2); } } else { //无点 加到List tc1.Items.Add(SClist[i]); } } foreach (var item in scdic) { SCTree.Children.Add(item.Value); } } public class TreeChildren { public string Name { get; set; } public List Items { get; set; } = new List(); public ObservableCollection Children { get; set; } = new ObservableCollection(); public TreeChildren() { } public TreeChildren(string name) { Name = name; } public ICommand ShowItems { get; set; } } public class GridData : PropertyChangedBase { public string Header { get; set; } public string Description { get; set; } public string Name { get; set; } public string Type { get; set; } public string Unint { get; set; } public string Min { get; set; } public string Max { get; set; } private string _cv; private string _sp; public string CurrentValue { get { return _cv; } set { _cv = value; NotifyOfPropertyChange(() => CurrentValue); } } public string Setpoint { get { return _sp; } set { _sp = value; NotifyOfPropertyChange(() => Setpoint); } } public ICommand Comfirm { get; set; } } } }