From 9264596831fee48419973a63ed57ad2231179466 Mon Sep 17 00:00:00 2001 From: hsc Date: Mon, 24 Nov 2025 15:57:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=BE=E5=A4=87=E5=BF=83?= =?UTF-8?q?=E8=B7=B3=E6=B7=BB=E5=8A=A0=E8=AE=BE=E5=A4=87=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BOB/App.xaml.cs | 17 +- BOB/Models/DeviceInfoModel.cs | 49 +++ BOB/Singleton/Devices.cs | 50 +-- BOB/Tasks/HeartbeatManager.cs | 159 ++++++++ BOB/ViewModels/Dialogs/BackfeedViewModel.cs | 351 ++++++++++++++++++ .../Dialogs/DeviceSettingViewModel.cs | 74 ---- BOB/ViewModels/Dialogs/EAEL9080ViewModel.cs | 181 +++++++++ BOB/ViewModels/Dialogs/IOBoardViewModel.cs | 139 +++++++ BOB/ViewModels/Dialogs/IT6724CViewModel.cs | 230 ++++++++++++ BOB/ViewModels/Dialogs/LQ7500-DViewModel.cs | 57 +++ BOB/ViewModels/Dialogs/PSB11000ViewModel.cs | 196 ++++++++++ BOB/ViewModels/Dialogs/SQ0030G1DViewModel.cs | 227 +++++++++++ .../Dialogs/WS-68030-380TViewModel.cs | 149 ++++++++ BOB/ViewModels/Dialogs/ZXKSViewModel.cs | 57 +++ BOB/ViewModels/ParametersManagerViewModel.cs | 184 +++++++-- .../UserControls/NumericalDisplayViewModel.cs | 69 ++++ BOB/Views/Dialogs/BackfeedView.xaml | 216 +++++++++++ BOB/Views/Dialogs/BackfeedView.xaml.cs | 36 ++ BOB/Views/Dialogs/DeviceSetting.xaml | 113 ------ BOB/Views/Dialogs/EAEL9080View.xaml | 125 +++++++ BOB/Views/Dialogs/EAEL9080View.xaml.cs | 36 ++ BOB/Views/Dialogs/IOBoardView.xaml | 86 +++++ BOB/Views/Dialogs/IOBoardView.xaml.cs | 36 ++ BOB/Views/Dialogs/IT6724CView.xaml | 168 +++++++++ BOB/Views/Dialogs/IT6724CView.xaml.cs | 37 ++ BOB/Views/Dialogs/LQ7500-DView.xaml | 21 ++ BOB/Views/Dialogs/LQ7500-DView.xaml.cs | 36 ++ BOB/Views/Dialogs/PSB11000View.xaml | 170 +++++++++ BOB/Views/Dialogs/PSB11000View.xaml.cs | 36 ++ BOB/Views/Dialogs/SQ0030G1DView.xaml | 204 ++++++++++ BOB/Views/Dialogs/SQ0030G1DView.xaml.cs | 36 ++ BOB/Views/Dialogs/WS-68030-380TView.xaml | 71 ++++ BOB/Views/Dialogs/WS-68030-380TView.xaml.cs | 36 ++ BOB/Views/Dialogs/ZXKSView.xaml | 21 ++ BOB/Views/Dialogs/ZXKSView.xaml.cs | 36 ++ BOB/Views/ParametersManager.xaml | 6 +- BOB/Views/UserControls/NumericalDisplay.xaml | 74 ++++ .../NumericalDisplay.xaml.cs} | 10 +- DeviceCommand/Base/ISerialPort.cs | 2 +- DeviceCommand/Base/ModbusRtu.cs | 6 +- DeviceCommand/Base/ModbusTcp.cs | 6 +- DeviceCommand/Base/Serial_Port.cs | 14 +- DeviceCommand/Base/TCP.cs | 22 +- DeviceCommand/Device/Backfeed.cs | 2 +- DeviceCommand/Device/E36233A.cs | 106 +++++- DeviceCommand/Device/EAEL9080.cs | 347 +++++++++++------ DeviceCommand/Device/IOBoard.cs | 112 +++++- DeviceCommand/Device/IT6724C.cs | 109 +++++- DeviceCommand/Device/IT6724CReverse.cs | 111 +++++- DeviceCommand/Device/LQ7500-D.cs | 106 +++++- DeviceCommand/Device/PSB11000.cs | 333 +++++++++++++---- DeviceCommand/Device/SQ0030G1D.cs | 152 +++++++- DeviceCommand/Device/WS-68030-380T.cs | 113 +++++- DeviceCommand/Device/ZXKS.cs | 101 ++++- DeviceCommand/DeviceCommand.csproj | 1 + Logger/LoggerHelper.cs | 32 +- Logger/LoggingInterceptor.cs | 32 +- Model/DeviceInfoModel.cs | 20 - 58 files changed, 4995 insertions(+), 531 deletions(-) create mode 100644 BOB/Models/DeviceInfoModel.cs create mode 100644 BOB/Tasks/HeartbeatManager.cs create mode 100644 BOB/ViewModels/Dialogs/BackfeedViewModel.cs delete mode 100644 BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/EAEL9080ViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/IOBoardViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/IT6724CViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/LQ7500-DViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/PSB11000ViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/SQ0030G1DViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/WS-68030-380TViewModel.cs create mode 100644 BOB/ViewModels/Dialogs/ZXKSViewModel.cs create mode 100644 BOB/ViewModels/UserControls/NumericalDisplayViewModel.cs create mode 100644 BOB/Views/Dialogs/BackfeedView.xaml create mode 100644 BOB/Views/Dialogs/BackfeedView.xaml.cs delete mode 100644 BOB/Views/Dialogs/DeviceSetting.xaml create mode 100644 BOB/Views/Dialogs/EAEL9080View.xaml create mode 100644 BOB/Views/Dialogs/EAEL9080View.xaml.cs create mode 100644 BOB/Views/Dialogs/IOBoardView.xaml create mode 100644 BOB/Views/Dialogs/IOBoardView.xaml.cs create mode 100644 BOB/Views/Dialogs/IT6724CView.xaml create mode 100644 BOB/Views/Dialogs/IT6724CView.xaml.cs create mode 100644 BOB/Views/Dialogs/LQ7500-DView.xaml create mode 100644 BOB/Views/Dialogs/LQ7500-DView.xaml.cs create mode 100644 BOB/Views/Dialogs/PSB11000View.xaml create mode 100644 BOB/Views/Dialogs/PSB11000View.xaml.cs create mode 100644 BOB/Views/Dialogs/SQ0030G1DView.xaml create mode 100644 BOB/Views/Dialogs/SQ0030G1DView.xaml.cs create mode 100644 BOB/Views/Dialogs/WS-68030-380TView.xaml create mode 100644 BOB/Views/Dialogs/WS-68030-380TView.xaml.cs create mode 100644 BOB/Views/Dialogs/ZXKSView.xaml create mode 100644 BOB/Views/Dialogs/ZXKSView.xaml.cs create mode 100644 BOB/Views/UserControls/NumericalDisplay.xaml rename BOB/Views/{Dialogs/DeviceSetting.xaml.cs => UserControls/NumericalDisplay.xaml.cs} (73%) delete mode 100644 Model/DeviceInfoModel.cs diff --git a/BOB/App.xaml.cs b/BOB/App.xaml.cs index 6c8b772..99f21c7 100644 --- a/BOB/App.xaml.cs +++ b/BOB/App.xaml.cs @@ -34,7 +34,7 @@ namespace BOB } else { - SystemConfig.Instance.Title = "设备1";//模拟打开的设备 + SystemConfig.Instance.Title = "设备2";//模拟打开的设备 } base.OnStartup(e); } @@ -42,7 +42,6 @@ namespace BOB protected override void OnInitialized() { base.OnInitialized(); - var regionManager = Container.Resolve(); regionManager.RequestNavigate("ShellViewManager", "MainView"); } @@ -55,7 +54,15 @@ namespace BOB //注册弹窗 containerRegistry.RegisterDialog("MessageBox"); containerRegistry.RegisterDialog("ParameterSetting"); - containerRegistry.RegisterDialog("DeviceSetting"); + containerRegistry.RegisterDialog("Backfeed"); + containerRegistry.RegisterDialog("EAEL9080"); + containerRegistry.RegisterDialog("IOBoard"); + containerRegistry.RegisterDialog("IT6724C"); + containerRegistry.RegisterDialog("LQ7500_D"); + containerRegistry.RegisterDialog("PSB11000"); + containerRegistry.RegisterDialog("SQ0030G1D"); + containerRegistry.RegisterDialog("WS_68030_380T"); + containerRegistry.RegisterDialog("ZXKS"); //注册全局变量 containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); @@ -63,8 +70,8 @@ namespace BOB } protected override void OnExit(ExitEventArgs e) { - var devices = Container.Resolve(); - devices.Dispose(); + //var devices = Container.Resolve(); + //devices.Dispose(); base.OnExit(e); } } diff --git a/BOB/Models/DeviceInfoModel.cs b/BOB/Models/DeviceInfoModel.cs new file mode 100644 index 0000000..507fd7f --- /dev/null +++ b/BOB/Models/DeviceInfoModel.cs @@ -0,0 +1,49 @@ +using Model; + +namespace BOB.Models +{ + public class DeviceInfoModel : BindableBase + { + private string _deviceName; + public string DeviceName + { + get => _deviceName; + set => SetProperty(ref _deviceName, value); + } + + private string _deviceType; + public string DeviceType + { + get => _deviceType; + set => SetProperty(ref _deviceType, value); + } + + private string _remark; + public string Remark + { + get => _remark; + set => SetProperty(ref _remark, value); + } + + private bool _isEnabled; + public bool IsEnabled + { + get => _isEnabled; + set => SetProperty(ref _isEnabled, value); + } + + private bool _isConnected; + public bool IsConnected + { + get => _isConnected; + set => SetProperty(ref _isConnected, value); + } + + private ICommunicationConfig _communicationConfig; + public ICommunicationConfig CommunicationConfig + { + get => _communicationConfig; + set => SetProperty(ref _communicationConfig, value); + } + } +} diff --git a/BOB/Singleton/Devices.cs b/BOB/Singleton/Devices.cs index 30589cd..8eb6750 100644 --- a/BOB/Singleton/Devices.cs +++ b/BOB/Singleton/Devices.cs @@ -21,13 +21,11 @@ namespace BOB.Singleton private readonly ProxyGenerator _proxyGen = new ProxyGenerator(); private readonly IInterceptor _loggingInterceptor = new LoggingInterceptor(); - //private ITcp E36233ADevice { get; set; } private ISerialPort IT6724CDevice { get; set; } - //private ISerialPort IT6724CReverseDevice{ get; set; } - private IModbusDevice EAEL9080Device { get; set; } + private ITcp EAEL9080Device { get; set; } private IModbusDevice IOBoardevice { get; set; } private IModbusDevice LQ7500_DDevice { get; set; } - private IModbusDevice PSB11000Device { get; set; } + private ITcp PSB11000Device { get; set; } private IModbusDevice WS_68030_380TDevice { get; set; } private ITcp SQ0030G1DTDevice { get; set; } private IModbusDevice ZXKSTDevice { get; set; } @@ -47,14 +45,21 @@ namespace BOB.Singleton case "DeviceCommand.Device.E36233A": if (device.CommunicationConfig is TcpConfig tcp1) { - BackfeedDevice=new Backfeed(tcp1); + BackfeedDevice = _proxyGen.CreateClassProxy( + new object[] { tcp1 }, + _loggingInterceptor + ); DeviceDic["Backfeed"] = BackfeedDevice; } break; + case "DeviceCommand.Device.IT6724CReverse": if (device.CommunicationConfig is SerialPortConfig sp3) { - BackfeedDevice = new Backfeed(sp3); + BackfeedDevice = _proxyGen.CreateClassProxy( + new object[] { sp3 }, + _loggingInterceptor + ); DeviceDic["Backfeed"] = BackfeedDevice; } break; @@ -62,8 +67,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.IT6724C": if (device.CommunicationConfig is SerialPortConfig sp1) { - IT6724CDevice = _proxyGen.CreateClassProxyWithTarget( - new IT6724C(sp1.COMPort, sp1.BaudRate, sp1.DataBit, sp1.StopBit, sp1.ParityBit, sp1.ReadTimeout, sp1.WriteTimeout), + var IT6724CDevice = _proxyGen.CreateClassProxy( + new object[] { sp1.COMPort, sp1.BaudRate, sp1.DataBit, sp1.StopBit, sp1.ParityBit, sp1.ReadTimeout, sp1.WriteTimeout }, _loggingInterceptor ); DeviceDic["IT6724C"] = IT6724CDevice; @@ -74,8 +79,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.LQ7500_D": if (device.CommunicationConfig is SerialPortConfig sp2) { - LQ7500_DDevice = _proxyGen.CreateClassProxyWithTarget( - new LQ7500_D(sp2.COMPort, sp2.BaudRate, sp2.DataBit, sp2.StopBit, sp2.ParityBit, sp2.ReadTimeout, sp2.WriteTimeout), + var LQ7500_DDevice = _proxyGen.CreateClassProxy( + new object[] { sp2.COMPort, sp2.BaudRate, sp2.DataBit, sp2.StopBit, sp2.ParityBit, sp2.ReadTimeout, sp2.WriteTimeout }, _loggingInterceptor ); DeviceDic["LQ7500_D"] = LQ7500_DDevice; @@ -86,8 +91,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.EAEL9080": if (device.CommunicationConfig is TcpConfig tcp2) { - EAEL9080Device = _proxyGen.CreateClassProxyWithTarget( - new EAEL9080(tcp2.IPAddress, tcp2.Port, tcp2.ReadTimeout, tcp2.WriteTimeout), + var EAEL9080Device = _proxyGen.CreateClassProxy( + new object[] { tcp2.IPAddress, tcp2.Port, tcp2.ReadTimeout, tcp2.WriteTimeout }, _loggingInterceptor ); DeviceDic["EAEL9080"] = EAEL9080Device; @@ -98,8 +103,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.IOBoard": if (device.CommunicationConfig is TcpConfig tcp3) { - IOBoardevice = _proxyGen.CreateClassProxyWithTarget( - new IOBoard(tcp3.IPAddress, tcp3.Port, tcp3.ReadTimeout, tcp3.WriteTimeout), + var IOBoardevice = _proxyGen.CreateClassProxy( + new object[] { tcp3.IPAddress, tcp3.Port, tcp3.ReadTimeout, tcp3.WriteTimeout }, _loggingInterceptor ); DeviceDic["IOBoard"] = IOBoardevice; @@ -110,8 +115,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.PSB11000": if (device.CommunicationConfig is TcpConfig tcp4) { - PSB11000Device = _proxyGen.CreateClassProxyWithTarget( - new PSB11000(tcp4.IPAddress, tcp4.Port, tcp4.ReadTimeout, tcp4.WriteTimeout), + var PSB11000Device = _proxyGen.CreateClassProxy( + new object[] { tcp4.IPAddress, tcp4.Port, tcp4.ReadTimeout, tcp4.WriteTimeout }, _loggingInterceptor ); DeviceDic["PSB11000"] = PSB11000Device; @@ -122,8 +127,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.WS_68030_380T": if (device.CommunicationConfig is TcpConfig tcp5) { - WS_68030_380TDevice = _proxyGen.CreateClassProxyWithTarget( - new WS_68030_380T(tcp5.IPAddress, tcp5.Port, tcp5.ReadTimeout, tcp5.WriteTimeout), + var WS_68030_380TDevice = _proxyGen.CreateClassProxy( + new object[] { tcp5.IPAddress, tcp5.Port, tcp5.ReadTimeout, tcp5.WriteTimeout }, _loggingInterceptor ); DeviceDic["WS_68030_380T"] = WS_68030_380TDevice; @@ -134,8 +139,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.SQ0030G1D": if (device.CommunicationConfig is TcpConfig tcp7) { - SQ0030G1DTDevice = _proxyGen.CreateClassProxyWithTarget( - new SQ0030G1D(tcp7.IPAddress, tcp7.Port, tcp7.ReadTimeout, tcp7.WriteTimeout), + var SQ0030G1DTDevice = _proxyGen.CreateClassProxy( + new object[] { tcp7.IPAddress, tcp7.Port, tcp7.ReadTimeout, tcp7.WriteTimeout }, _loggingInterceptor ); DeviceDic["SQ0030G1D"] = SQ0030G1DTDevice; @@ -146,8 +151,8 @@ namespace BOB.Singleton case "DeviceCommand.Device.ZXKS": if (device.CommunicationConfig is TcpConfig tcp6) { - ZXKSTDevice = _proxyGen.CreateClassProxyWithTarget( - new ZXKS(tcp6.IPAddress, tcp6.Port, tcp6.ReadTimeout, tcp6.WriteTimeout), + var ZXKSTDevice = _proxyGen.CreateClassProxy( + new object[] { tcp6.IPAddress, tcp6.Port, tcp6.ReadTimeout, tcp6.WriteTimeout }, _loggingInterceptor ); DeviceDic["ZXKS"] = ZXKSTDevice; @@ -159,6 +164,7 @@ namespace BOB.Singleton throw new NotSupportedException($"未知设备类型:{device.DeviceType}"); } + } } diff --git a/BOB/Tasks/HeartbeatManager.cs b/BOB/Tasks/HeartbeatManager.cs new file mode 100644 index 0000000..4bb5afe --- /dev/null +++ b/BOB/Tasks/HeartbeatManager.cs @@ -0,0 +1,159 @@ +using DeviceCommand.Base; +using DeviceCommand.Device; +using Logger; + + +namespace BOB.Tasks +{ + public class HeartbeatManager where T : class + { + private readonly T _device; + private readonly CancellationTokenSource _cancellationTokenSource; + private Task? _heartbeatTask; + private const int HeartbeatInterval = 3000; + bool IsActive = false; + int ReConnectionAttempts = 0; + private const int MaxReconnectAttempts = 10; + + public HeartbeatManager(T device) + { + _device = device ?? throw new ArgumentNullException(nameof(device)); + _cancellationTokenSource = new CancellationTokenSource(); + } + + // 启动设备的心跳 + public void StartHeartbeat() + { + if (_heartbeatTask != null) + return; + + _heartbeatTask = Task.Run(() => HeartbeatLoop(_device, _cancellationTokenSource.Token)); + } + + // 停止设备的心跳 + public void StopHeartbeat() + { + IsActive = false; + _cancellationTokenSource.Cancel(); + _heartbeatTask?.Wait(); + _heartbeatTask = null; + } + + private async Task HeartbeatLoop(T device, CancellationToken ct) + { + while (!ct.IsCancellationRequested) + { + await Task.Delay(HeartbeatInterval, ct); + + try + { + switch (device) + { + case EAEL9080 eAEL9080: + await eAEL9080.SendAsync("SYSTem:REMote\r\n", ct); + IsActive = true; + break; + + case IT6724C iT6724C: + await iT6724C.SendAsync("SYSTem:REMote\r\n", ct); + IsActive = true; + break; + + case PSB11000 pSB11000: + await pSB11000.SendAsync("SYSTem:REMote\r\n", ct); + IsActive = true; + break; + + case SQ0030G1D sQ0030G1D: + await sQ0030G1D.SendAsync("SYSTem:REMote\r\n", ct); + IsActive = true; + break; + + case WS_68030_380T wS_68030_380T: + await wS_68030_380T.ReadCoilsAsync(1,0,1); + IsActive = true; + break; + + case IOBoard iOBoard: + await iOBoard.ReadCoilsAsync(1, 0, 1); + IsActive = true; + break; + + case LQ7500_D lQ7500_D: + await lQ7500_D.ReadCoilsAsync(1, 0, 1); + IsActive = true; + break; + + case ZXKS zXKS: + await zXKS.ReadCoilsAsync(1, 0, 1); + IsActive = true; + break; + + case Backfeed backfeed: + if (backfeed.CurrentInstance is E36233A e36233A) + { + await e36233A.SendAsync("SYSTem:REMote\r\n", ct); + IsActive = true; + } + else if (backfeed.CurrentInstance is IT6724CReverse iT6724CReverse) + { + await iT6724CReverse.SendAsync("SYSTem:REMote\r\n", ct); + IsActive = true; + } + break; + } + + } + catch (Exception ex) + { + IsActive = false; + ReConnectionAttempts++; + if (MaxReconnectAttempts < ReConnectionAttempts) + { + LoggerHelper.ErrorWithNotify($"重连次数超过上限,停止重连:{device.GetType().Name}"); + StopHeartbeat(); + return; + } + await ReconnectDevice(device, ct); + } + } + } + + private async Task ReconnectDevice(T device, CancellationToken ct) + { + try + { + bool result = false; + if (device is ITcp itcpDevice) + { + result = await itcpDevice.ConnectAsync(CancellationToken.None); + } + else if (device is IModbusDevice imodbusDevice) + { + result = await imodbusDevice.ConnectAsync(CancellationToken.None); + } + else if (device is ISerialPort iserialPortDevice) + { + result = await iserialPortDevice.ConnectAsync(CancellationToken.None); + } + else if (device is Backfeed backfeedDevice) + { + if (backfeedDevice.CurrentInstance is ITcp itcpDevice1) + { + result = await itcpDevice1.ConnectAsync(CancellationToken.None); + } + else if (backfeedDevice.CurrentInstance is ISerialPort iserialPortDevice1) + { + result = await iserialPortDevice1.ConnectAsync(CancellationToken.None); + } + } + if (result == false) { LoggerHelper.ErrorWithNotify($"重连失败:{device.GetType().Name}"); } + else ReConnectionAttempts=0; + } + catch (Exception ex) + { + LoggerHelper.ErrorWithNotify($"重连异常:{device.GetType().Name}"+ex.Message); + } + } + } +} diff --git a/BOB/ViewModels/Dialogs/BackfeedViewModel.cs b/BOB/ViewModels/Dialogs/BackfeedViewModel.cs new file mode 100644 index 0000000..3e8394d --- /dev/null +++ b/BOB/ViewModels/Dialogs/BackfeedViewModel.cs @@ -0,0 +1,351 @@ +using BOB.Singleton; +using DeviceCommand.Device; +using Logger; +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using SqlSugar; +using System; +using System.Windows.Input; + +namespace BOB.ViewModels.Dialogs +{ + public class BackfeedViewModel : BindableBase, IDialogAware + { + #region 属性 + + private string _Title = "反灌电压"; + public string Title + { + get { return _Title; } + set { SetProperty(ref _Title, value); } + } + + private string _设备标识字符串; + public string 设备标识字符串 + { + get { return _设备标识字符串; } + set { SetProperty(ref _设备标识字符串, value); } + } + + private string _输出电压; + public string 输出电压 + { + get { return _输出电压; } + set { SetProperty(ref _输出电压, value); } + } + + private string _输出电流; + public string 输出电流 + { + get { return _输出电流; } + set { SetProperty(ref _输出电流, value); } + } + + private string _OCP电流; + public string OCP电流 + { + get { return _OCP电流; } + set { SetProperty(ref _OCP电流, value); } + } + + private string _OVP电压; + public string OVP电压 + { + get { return _OVP电压; } + set { SetProperty(ref _OVP电压, value); } + } + + private string _OPP功率; + public string OPP功率 + { + get { return _OPP功率; } + set { SetProperty(ref _OPP功率, value); } + } + + #endregion + + #region 命令 + + public ICommand ConnectCommand { get; private set; } + public ICommand DisconnectCommand { get; private set; } + public ICommand QueryDeviceCommand { get; private set; } + public ICommand SetVoltageCommand { get; private set; } + public ICommand SetCurrentCommand { get; private set; } + public ICommand EnableOCPCommand { get; private set; } + public ICommand DisableOCPCommand { get; private set; } + public ICommand SetOCPCommand { get; private set; } + public ICommand EnableOVPCommand { get; private set; } + public ICommand DisableOVPCommand { get; private set; } + public ICommand SetOVPCommand { get; private set; } + public ICommand EnableOPPCommand { get; private set; } + public ICommand DisableOPPCommand { get; private set; } + public ICommand SetOPPCommand { get; private set; } + public ICommand CloseCommand { get; private set; } + + #endregion + + + private IEventAggregator _eventAggregator { get;set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + private object device { get; set; } + + public BackfeedViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + + // Initialize commands + ConnectCommand = new AsyncDelegateCommand(OnConnect); + DisconnectCommand = new DelegateCommand(OnDisconnect); + QueryDeviceCommand = new AsyncDelegateCommand(OnQueryDevice); + SetVoltageCommand = new AsyncDelegateCommand(OnSetVoltage); + SetCurrentCommand = new AsyncDelegateCommand(OnSetCurrent); + EnableOCPCommand = new AsyncDelegateCommand(OnEnableOCP); + DisableOCPCommand = new AsyncDelegateCommand(OnDisableOCP); + SetOCPCommand = new AsyncDelegateCommand(OnSetOCP); + EnableOVPCommand = new AsyncDelegateCommand(OnEnableOVP); + DisableOVPCommand = new AsyncDelegateCommand(OnDisableOVP); + SetOVPCommand = new AsyncDelegateCommand(OnSetOVP); + EnableOPPCommand = new AsyncDelegateCommand(OnEnableOPP); + DisableOPPCommand = new AsyncDelegateCommand(OnDisableOPP); + SetOPPCommand = new AsyncDelegateCommand(OnSetOPP); + CloseCommand = new DelegateCommand(OnClose); + } + + + #region Command Handlers + + private async Task OnConnect() + { + if (device is E36233A e36233A) + { + await e36233A.ConnectAsync(); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.ConnectAsync(); + } + } + + private void OnDisconnect() + { + if (device is E36233A e36233A) + { + e36233A.Close(); + } + else if (device is IT6724CReverse it6724CReverse) + { + it6724CReverse.Close(); + } + } + + private async Task OnQueryDevice() + { + if (device is E36233A e36233A) + { + 设备标识字符串 = await e36233A.查询设备信息(); + } + else if (device is IT6724CReverse it6724CReverse) + { + 设备标识字符串 = await it6724CReverse.查询设备信息(); + } + } + + private async Task OnSetVoltage() + { + if (device is E36233A e36233A) + { + await e36233A.设置电压(Convert.ToDouble(输出电压)); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置电压(Convert.ToDouble(输出电压)); + } + } + + private async Task OnSetCurrent() + { + if (device is E36233A e36233A) + { + await e36233A.设置电流(Convert.ToDouble(输出电流)); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置电流(Convert.ToDouble(输出电流)); + } + } + + private async Task OnEnableOCP() + { + if (device is E36233A e36233A) + { + await e36233A.设置OCP开关(true); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置OCP开关(true); + } + } + + private async Task OnDisableOCP() + { + if (device is E36233A e36233A) + { + await e36233A.设置OCP开关(false); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置OCP开关(false); + } + } + + private async Task OnSetOCP() + { + if (device is E36233A e36233A) + { + await e36233A.设置电流保护OCP电流(Convert.ToDouble(OCP电流)); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置电流保护OCP电流(Convert.ToDouble(OCP电流)); + } + } + + private async Task OnEnableOVP() + { + if (device is E36233A e36233A) + { + await e36233A.设置OVP开关(true); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置OVP开关(true); + } + } + + private async Task OnDisableOVP() + { + if (device is E36233A e36233A) + { + await e36233A.设置OVP开关(false); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置OVP开关(false); + } + } + + private async Task OnSetOVP() + { + if (device is E36233A e36233A) + { + await e36233A.设置电压保护OVP电压(Convert.ToDouble(OVP电压)); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置电压保护OVP电压(Convert.ToDouble(OVP电压)); + } + } + + private async Task OnEnableOPP() + { + if (device is E36233A e36233A) + { + await e36233A.设置OVP开关(true); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置OVP开关(true); + } + } + + private async Task OnDisableOPP() + { + if (device is E36233A e36233A) + { + await e36233A.设置OVP开关(false); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置OVP开关(false); + } + } + + private async Task OnSetOPP() + { + if (device is E36233A e36233A) + { + await e36233A.设置功率保护功率(Convert.ToDouble(OPP功率)); + } + else if (device is IT6724CReverse it6724CReverse) + { + await it6724CReverse.设置功率保护功率(Convert.ToDouble(OPP功率)); + } + } + + private void OnClose() + { + RequestClose.Invoke(); + } + + + #endregion + + #region Dialog规范 + + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + // Implement cleanup logic here if needed + } + + public void OnDialogOpened(IDialogParameters parameters) + { + try + { + if (_devices.DeviceDic.ContainsKey("E36233A")) + { + var a = _devices.DeviceDic["E36233A"] as E36233A; + if (a != null) + { + device = a; + } + else + { + LoggerHelper.ErrorWithNotify("设备没有初始化无法打开测试界面"); + RequestClose.Invoke(); + } + } + else if (_devices.DeviceDic.ContainsKey("IT6724CReverse")) + { + var a = _devices.DeviceDic["IT6724CReverse"] as IT6724CReverse; + if (a != null) + { + device = a; + } + else + { + LoggerHelper.ErrorWithNotify("设备没有初始化无法打开测试界面"); + RequestClose.Invoke(); + } + + } + } + catch (Exception) + { + LoggerHelper.ErrorWithNotify("找不到设备无法打开测试界面"); + } + + } + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs b/BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs deleted file mode 100644 index 5d84ffd..0000000 --- a/BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs +++ /dev/null @@ -1,74 +0,0 @@ -using BOB.Models; -using Common.PubEvent; -using Model; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Input; -using static BOB.Models.ParameterModel; - -namespace BOB.ViewModels.Dialogs -{ - public class DeviceSettingViewModel : BindableBase, IDialogAware - { - #region 属性 - private string _title = "设备设置界面"; - public string Title - { - get => _title; - set => SetProperty(ref _title, value); - } - private DeviceInfoModel _Device; - public DeviceInfoModel Device - { - get => _Device; - set => SetProperty(ref _Device, value); - } - #endregion - public DialogCloseListener RequestClose { get; set; } - private GlobalVariables _globalVariables; - private IEventAggregator _eventAggregator; - public ICommand CancelCommand { get; set; } - public ICommand SaveCommand { get; set; } - public DeviceSettingViewModel(GlobalVariables globalVariables, IEventAggregator eventAggregator) - { - _eventAggregator = eventAggregator; - _globalVariables = globalVariables; - CancelCommand = new DelegateCommand(Cancel); - SaveCommand = new DelegateCommand(Save); - } - - - - private void Save() - { - RequestClose.Invoke(ButtonResult.OK); - } - - private void Cancel() - { - RequestClose.Invoke(ButtonResult.No); - } - #region Prism Dialog 规范 - public bool CanCloseDialog() - { - return true; - } - - public void OnDialogClosed() - { - _eventAggregator.GetEvent().Publish(false); - } - - public void OnDialogOpened(IDialogParameters parameters) - { - _eventAggregator.GetEvent().Publish(true); - - } - #endregion - } -} diff --git a/BOB/ViewModels/Dialogs/EAEL9080ViewModel.cs b/BOB/ViewModels/Dialogs/EAEL9080ViewModel.cs new file mode 100644 index 0000000..65c1ea2 --- /dev/null +++ b/BOB/ViewModels/Dialogs/EAEL9080ViewModel.cs @@ -0,0 +1,181 @@ +using BOB.Singleton; +using Prism.Commands; +using Prism.Mvvm; +using Prism.Events; +using System; +using System.Threading.Tasks; +using System.Windows.Input; +using DeviceCommand.Device; +using Logger; +using BOB.ViewModels.UserControls; + +namespace BOB.ViewModels.Dialogs +{ + public class EAEL9080ViewModel : BindableBase, IDialogAware + { + #region 属性 + private string _Title = "低压直流负载"; + private string _设备标识字符串; + private string _负载模式; + private string _电流LA; + private string _电流LB; + private NumericalDisplayViewModel _电压MV=new(); + private NumericalDisplayViewModel _电流MV = new(); + private NumericalDisplayViewModel _功率MV=new(); + + public string Title + { + get { return _Title; } + set { SetProperty(ref _Title, value); } + } + + public string 设备标识字符串 + { + get { return _设备标识字符串; } + set { SetProperty(ref _设备标识字符串, value); } + } + + public string 负载模式 + { + get { return _负载模式; } + set { SetProperty(ref _负载模式, value); } + } + + public string 电流LA + { + get { return _电流LA; } + set { SetProperty(ref _电流LA, value); } + } + + public string 电流LB + { + get { return _电流LB; } + set { SetProperty(ref _电流LB, value); } + } + public NumericalDisplayViewModel 电压MV + { + get { return _电压MV; } + set { SetProperty(ref _电压MV, value); } + } + public NumericalDisplayViewModel 电流MV + { + get { return _电流MV; } + set { SetProperty(ref _电流MV, value); } + } + public NumericalDisplayViewModel 功率MV + { + get { return _功率MV; } + set { SetProperty(ref _功率MV, value); } + } + #endregion + + #region 命令 + public ICommand 连接命令 { get; private set; } + public ICommand 断开命令 { get; private set; } + public ICommand 设置为远程模式命令 { get; private set; } + public ICommand 设置负载工作模式命令 { get; private set; } + public ICommand 电源输出开命令 { get; private set; } + public ICommand 电源输出关命令 { get; private set; } + public ICommand 关闭命令 { get; private set; } + public ICommand 查询设备信息命令 { get; private set; } + + #endregion + + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + private EAEL9080 device { get; set; } + + public EAEL9080ViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + 连接命令 = new AsyncDelegateCommand(OnConnect); + 断开命令 = new DelegateCommand(OnDisconnect); + 设置为远程模式命令 = new AsyncDelegateCommand(OnSetRemoteMode); + 设置负载工作模式命令 = new AsyncDelegateCommand(OnSetLoadMode); + 电源输出开命令 = new AsyncDelegateCommand(OnPowerOn); + 电源输出关命令 = new AsyncDelegateCommand(OnPowerOff); + 关闭命令 = new DelegateCommand(OnOff); + 查询设备信息命令 = new AsyncDelegateCommand(OnQueryDeviceInfo); + } + + private async Task OnQueryDeviceInfo() + { + 设备标识字符串 = await device.查询设备信息(); + } + + private void OnOff() + { + RequestClose.Invoke(); + } + + private async Task OnConnect() + { + await device.ConnectAsync(); + } + + private async void OnDisconnect() + { + device.Close(); + } + + + private async Task OnSetRemoteMode() + { + await device.设置远程控制(true); + } + + private async Task OnSetLoadMode() + { + + } + + private async Task OnPowerOn() + { + await device.打开输出(); + } + + private async Task OnPowerOff() + { + await device.关闭输出(); + } + + #region dialog规范 + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + try + { + var a = _devices.DeviceDic["EAEL9080"] as EAEL9080; + if (a != null) + { + device = a; + } + else + { + LoggerHelper.ErrorWithNotify("设备没有初始化无法打开测试界面"); + RequestClose.Invoke(); + } + } + catch (Exception) + { + LoggerHelper.ErrorWithNotify("找不到设备无法打开测试界面"); + } + + } + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/IOBoardViewModel.cs b/BOB/ViewModels/Dialogs/IOBoardViewModel.cs new file mode 100644 index 0000000..052a9de --- /dev/null +++ b/BOB/ViewModels/Dialogs/IOBoardViewModel.cs @@ -0,0 +1,139 @@ +using BOB.Singleton; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace BOB.ViewModels.Dialogs +{ + public class IOBoardViewModel : BindableBase, IDialogAware + { + #region 属性 + + private string _title = "IO板卡"; + + public string Title + { + get { return _title; } + set { SetProperty(ref _title, value); } + } + + private int _startAddress; + public int StartAddress + { + get { return _startAddress; } + set { SetProperty(ref _startAddress, value); } + } + + public ObservableCollection AddressNames { get; set; } + + private string _offset; + public string Offset + { + get { return _offset; } + set { SetProperty(ref _offset, value); } + } + + private string _batchWriteStatus; + public string BatchWriteStatus + { + get { return _batchWriteStatus; } + set { SetProperty(ref _batchWriteStatus, value); } + } + + #endregion + + #region 命令 + + public ICommand ConnectCommand { get; private set; } + public ICommand DisconnectCommand { get; private set; } + public ICommand PowerOnCommand { get; private set; } + public ICommand PowerOffCommand { get; private set; } + public ICommand SetCommand { get; private set; } + public ICommand ReadCommand { get; private set; } + public ICommand CloseCommand { get; private set; } + + #endregion + + + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + public IOBoardViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + ConnectCommand = new DelegateCommand(OnConnect); + DisconnectCommand = new DelegateCommand(OnDisconnect); + PowerOnCommand = new DelegateCommand(OnPowerOn); + PowerOffCommand = new DelegateCommand(OnPowerOff); + SetCommand = new DelegateCommand(OnSet); + ReadCommand = new DelegateCommand(OnRead); + CloseCommand = new DelegateCommand(OnClose); + } + + + private void OnConnect() + { + // 连接逻辑 + Console.WriteLine("连接设备..."); + } + + private void OnDisconnect() + { + // 断开连接逻辑 + Console.WriteLine("断开设备..."); + } + + private void OnPowerOn() + { + // 开启电源逻辑 + Console.WriteLine("电源开启..."); + } + + private void OnPowerOff() + { + // 关闭电源逻辑 + Console.WriteLine("电源关闭..."); + } + + private void OnSet() + { + // 设置逻辑 + Console.WriteLine("设置..."); + } + + private void OnRead() + { + // 读取逻辑 + Console.WriteLine("读取..."); + } + private void OnClose() + { + RequestClose.Invoke(); + } + #region dialog规范 + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + + } + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/IT6724CViewModel.cs b/BOB/ViewModels/Dialogs/IT6724CViewModel.cs new file mode 100644 index 0000000..6a21d1c --- /dev/null +++ b/BOB/ViewModels/Dialogs/IT6724CViewModel.cs @@ -0,0 +1,230 @@ +using BOB.Singleton; +using DeviceCommand.Device; +using Logger; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace BOB.ViewModels.Dialogs +{ + public class IT6724CViewModel : BindableBase, IDialogAware + { + + #region 属性 + + private string _title = "低压直流电源"; + public string Title + { + get { return _title; } + set { SetProperty(ref _title, value); } + } + + private string _设备标识字符串; + public string 设备标识字符串 + { + get { return _设备标识字符串; } + set { SetProperty(ref _设备标识字符串, value); } + } + + private string _输出电压; + public string 输出电压 + { + get { return _输出电压; } + set { SetProperty(ref _输出电压, value); } + } + + private string _输出电流; + public string 输出电流 + { + get { return _输出电流; } + set { SetProperty(ref _输出电流, value); } + } + + private string _OCP电流; + public string OCP电流 + { + get { return _OCP电流; } + set { SetProperty(ref _OCP电流, value); } + } + + private string _OVP电压; + public string OVP电压 + { + get { return _OVP电压; } + set { SetProperty(ref _OVP电压, value); } + } + + #endregion + #region 命令 + public ICommand ConnectCommand { get; private set; } + public ICommand DisconnectCommand { get; private set; } + public ICommand PowerOnCommand { get; private set; } + public ICommand PowerOffCommand { get; private set; } + public ICommand SetOutputVoltageCommand { get; private set; } + public ICommand SetOutputCurrentCommand { get; private set; } + public ICommand SetRemoteModeCommand { get; private set; } + public ICommand QueryDeviceInfoCommand { get; private set; } + public ICommand EnableOCPCommand { get; private set; } + public ICommand DisableOCPCommand { get; private set; } + public ICommand ClearOCPAlarmCommand { get; private set; } + public ICommand SetOCPCommand { get; private set; } + public ICommand EnableOVPCommand { get; private set; } + public ICommand DisableOVPCommand { get; private set; } + public ICommand ClearOVPAlarmCommand { get; private set; } + public ICommand SetOVPCommand { get; private set; } + public ICommand CloseCommand { get; private set; } + + #endregion + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + private IT6724C device { get; set; } + public IT6724CViewModel(IContainerProvider containerProvider) + { + ConnectCommand = new AsyncDelegateCommand(OnConnect); + DisconnectCommand = new DelegateCommand(OnDisconnect); + PowerOnCommand = new AsyncDelegateCommand(OnPowerOn); + PowerOffCommand = new AsyncDelegateCommand(OnPowerOff); + SetOutputVoltageCommand = new AsyncDelegateCommand(OnSetOutputVoltage); + SetOutputCurrentCommand = new AsyncDelegateCommand(OnSetOutputCurrent); + SetRemoteModeCommand = new AsyncDelegateCommand(OnSetRemoteMode); + QueryDeviceInfoCommand = new AsyncDelegateCommand(OnQueryDeviceInfo); + EnableOCPCommand = new AsyncDelegateCommand(OnEnableOCP); + DisableOCPCommand = new AsyncDelegateCommand(OnDisableOCP); + ClearOCPAlarmCommand = new AsyncDelegateCommand(OnClearOCPAlarm); + SetOCPCommand = new AsyncDelegateCommand(OnSetOCP); + EnableOVPCommand = new AsyncDelegateCommand(OnEnableOVP); + DisableOVPCommand = new AsyncDelegateCommand(OnDisableOVP); + ClearOVPAlarmCommand = new AsyncDelegateCommand(OnClearOVPAlarm); + SetOVPCommand = new AsyncDelegateCommand(OnSetOVP); + CloseCommand = new DelegateCommand(OnClose); + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + } + + #region 命令处理方法 + private void OnClose() + { + RequestClose.Invoke(); + } + private async Task OnConnect() + { + await device.ConnectAsync(); + } + + private void OnDisconnect() + { + device.Close(); + } + + private async Task OnPowerOn() + { + await device.设置电源输出(true); + } + + private async Task OnPowerOff() + { + await device.设置电源输出(false); + } + + private async Task OnSetOutputVoltage() + { + await device.设置电压(double.Parse(输出电压)); + } + + private async Task OnSetOutputCurrent() + { + await device.设置电流(double.Parse(输出电流)); + } + + private async Task OnSetRemoteMode() + { + await device.设置为远程模式(); + } + + private async Task OnQueryDeviceInfo() + { + 设备标识字符串=await device.查询设备信息(); + } + + private async Task OnEnableOCP() + { + await device.设置OCP开关(true); + } + + private async Task OnDisableOCP() + { + await device.设置OCP开关(false); + } + + private async Task OnClearOCPAlarm() + { + await device.清除电流保护(); + } + + private async Task OnSetOCP() + { + await device.设置电流保护OCP电流(double.Parse(OCP电流)); + } + + private async Task OnEnableOVP() + { + await device.设置OVP开关(true); + } + + private async Task OnDisableOVP() + { + await device.设置OVP开关(false); + } + + private async Task OnClearOVPAlarm() + { + await device.清除电压保护(); + } + + private async Task OnSetOVP() + { + await device.设置电压保护OVP电压(double.Parse(OVP电压)); + } + + #endregion + #region dialog规范 + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + try + { + var a = _devices.DeviceDic["IT6724C"] as IT6724C; + if (a != null) + { + device = a; + } + else + { + LoggerHelper.ErrorWithNotify("设备没有初始化无法打开测试界面"); + RequestClose.Invoke(); + } + } + catch (Exception) + { + LoggerHelper.ErrorWithNotify("找不到设备无法打开测试界面"); + } + } + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/LQ7500-DViewModel.cs b/BOB/ViewModels/Dialogs/LQ7500-DViewModel.cs new file mode 100644 index 0000000..84a47b5 --- /dev/null +++ b/BOB/ViewModels/Dialogs/LQ7500-DViewModel.cs @@ -0,0 +1,57 @@ +using BOB.Singleton; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BOB.ViewModels.Dialogs +{ + public class LQ7500_DViewModel : BindableBase, IDialogAware + { + + #region 属性 + private string _Title = "水冷机"; + + public string Title + { + get { return _Title; } + set { SetProperty(ref _Title, value); } + } + + + #endregion + #region 命令 + + + #endregion + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + public LQ7500_DViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + } + + #region dialog规范 + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + + } + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/PSB11000ViewModel.cs b/BOB/ViewModels/Dialogs/PSB11000ViewModel.cs new file mode 100644 index 0000000..fb593a0 --- /dev/null +++ b/BOB/ViewModels/Dialogs/PSB11000ViewModel.cs @@ -0,0 +1,196 @@ +using BOB.Singleton; +using DeviceCommand.Device; +using Logger; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace BOB.ViewModels.Dialogs +{ + public class PSB11000ViewModel : BindableBase, IDialogAware + { + + #region 属性 + private string _Title = "反灌高压直流双向电源"; + public string Title + { + get { return _Title; } + set { SetProperty(ref _Title, value); } + } + + private string _设备标识字符串; + public string 设备标识字符串 + { + get { return _设备标识字符串; } + set { SetProperty(ref _设备标识字符串, value); } + } + + private string _输出电压; + public string 输出电压 + { + get { return _输出电压; } + set { SetProperty(ref _输出电压, value); } + } + + private string _输出电流; + public string 输出电流 + { + get { return _输出电流; } + set { SetProperty(ref _输出电流, value); } + } + + private string _OCP电流; + public string OCP电流 + { + get { return _OCP电流; } + set { SetProperty(ref _OCP电流, value); } + } + + + #endregion + #region 命令 + + public ICommand ConnectCommand { get; private set; } + public ICommand DisconnectCommand { get; private set; } + public ICommand PowerOnCommand { get; private set; } + public ICommand PowerOffCommand { get; private set; } + public ICommand SetRemoteModeCommand { get; private set; } + public ICommand QueryDeviceInfoCommand { get; private set; } + public ICommand SwitchWorkingModeCommand { get; private set; } + public ICommand SwitchDCSourceModeCommand { get; private set; } + public ICommand SwitchLoadModeCommand { get; private set; } + public ICommand SetCCVoltageCommand { get; private set; } + public ICommand SetCCCurrentCommand { get; private set; } + public ICommand SetOCPCurrentCommand { get; private set; } + public ICommand CloseCommand { get; private set; } + + #endregion + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + private PSB11000 device; + public PSB11000ViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + ConnectCommand = new AsyncDelegateCommand(OnConnect); + DisconnectCommand = new DelegateCommand(OnDisconnect); + PowerOnCommand = new AsyncDelegateCommand(OnPowerOn); + PowerOffCommand = new AsyncDelegateCommand(OnPowerOff); + SetRemoteModeCommand = new AsyncDelegateCommand(OnSetRemoteMode); + QueryDeviceInfoCommand = new AsyncDelegateCommand(OnQueryDeviceInfo); + SwitchWorkingModeCommand = new AsyncDelegateCommand(OnSwitchWorkingMode); + SwitchDCSourceModeCommand = new AsyncDelegateCommand(OnSwitchDCSourceMode); + SwitchLoadModeCommand = new AsyncDelegateCommand(OnSwitchLoadMode); + SetCCVoltageCommand = new AsyncDelegateCommand(OnSetCCVoltage); + SetCCCurrentCommand = new AsyncDelegateCommand(OnSetCCCurrent); + SetOCPCurrentCommand = new AsyncDelegateCommand(OnSetOCPCurrent); + CloseCommand = new DelegateCommand(OnClose); + + } + #region Command Handlers + private void OnClose() + { + RequestClose.Invoke(); + } + private async Task OnConnect() + { + await device.ConnectAsync(); + } + + private void OnDisconnect() + { + device.Close(); + } + + private async Task OnPowerOn() + { + await device.打开输出(); + } + + private async Task OnPowerOff() + { + await device.关闭输出(); + } + + private async Task OnSetRemoteMode() + { + await device.设置远程控制(true); + } + + private async Task OnQueryDeviceInfo() + { + 设备标识字符串=await device.查询设备信息(); + } + + private async Task OnSwitchWorkingMode() + { + + } + + private async Task OnSwitchDCSourceMode() + { + // Logic for switching DC source mode + } + + private async Task OnSwitchLoadMode() + { + // Logic for switching load mode + } + + private async Task OnSetCCVoltage() + { + // Logic for setting CC voltage + } + + private async Task OnSetCCCurrent() + { + // Logic for setting CC current + } + + private async Task OnSetOCPCurrent() + { + + } + #endregion + #region dialog规范 + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + try + { + var a = _devices.DeviceDic["PSB11000"] as PSB11000; + if (a != null) + { + device = a; + } + else + { + LoggerHelper.ErrorWithNotify("设备没有初始化无法打开测试界面"); + RequestClose.Invoke(); + } + } + catch (Exception) + { + LoggerHelper.ErrorWithNotify("找不到设备无法打开测试界面"); + } + + } + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/SQ0030G1DViewModel.cs b/BOB/ViewModels/Dialogs/SQ0030G1DViewModel.cs new file mode 100644 index 0000000..cdefd00 --- /dev/null +++ b/BOB/ViewModels/Dialogs/SQ0030G1DViewModel.cs @@ -0,0 +1,227 @@ +using BOB.Singleton; +using DeviceCommand.Device; +using Logger; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace BOB.ViewModels.Dialogs +{ + public class SQ0030G1DViewModel : BindableBase, IDialogAware + { + + #region 属性 + + private string _Title = "交流电源"; + public string Title + { + get { return _Title; } + set { SetProperty(ref _Title, value); } + } + + private string _UPhaseVoltage; + public string UPhaseVoltage + { + get { return _UPhaseVoltage; } + set { SetProperty(ref _UPhaseVoltage, value); } + } + + private string _VPhaseVoltage; + public string VPhaseVoltage + { + get { return _VPhaseVoltage; } + set { SetProperty(ref _VPhaseVoltage, value); } + } + + private string _WPhaseVoltage; + public string WPhaseVoltage + { + get { return _WPhaseVoltage; } + set { SetProperty(ref _WPhaseVoltage, value); } + } + + private string _CommonOutputVoltage; + public string CommonOutputVoltage + { + get { return _CommonOutputVoltage; } + set { SetProperty(ref _CommonOutputVoltage, value); } + } + + private string _CommonOutputFrequency; + public string CommonOutputFrequency + { + get { return _CommonOutputFrequency; } + set { SetProperty(ref _CommonOutputFrequency, value); } + } + + private string _StepOutputVoltage; + public string StepOutputVoltage + { + get { return _StepOutputVoltage; } + set { SetProperty(ref _StepOutputVoltage, value); } + } + + private string _StepOutputFrequency; + public string StepOutputFrequency + { + get { return _StepOutputFrequency; } + set { SetProperty(ref _StepOutputFrequency, value); } + } + + private string _StepOutputVoltageGroup; + public string StepOutputVoltageGroup + { + get { return _StepOutputVoltageGroup; } + set { SetProperty(ref _StepOutputVoltageGroup, value); } + } + + private string _StepOutputFrequencyGroup; + public string StepOutputFrequencyGroup + { + get { return _StepOutputFrequencyGroup; } + set { SetProperty(ref _StepOutputFrequencyGroup, value); } + } + + #endregion + + #region 命令 + + public ICommand ConnectCommand { get; private set; } + public ICommand DisconnectCommand { get; private set; } + public ICommand SetVoltageLevelLowCommand { get; private set; } + public ICommand SetVoltageLevelHighCommand { get; private set; } + public ICommand SetThreePhaseVoltageCommand { get; private set; } + public ICommand SetCommonOutputVoltageCommand { get; private set; } + public ICommand SetCommonOutputFrequencyCommand { get; private set; } + public ICommand SetStepOutputVoltageCommand { get; private set; } + public ICommand SetStepOutputFrequencyCommand { get; private set; } + public ICommand OpenPowerSupplyCommand { get; private set; } + public ICommand ClosePowerSupplyCommand { get; private set; } + public ICommand CloseCommand { get; private set; } + + #endregion + + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + private SQ0030G1D device { get; set; } + public SQ0030G1DViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + ConnectCommand = new AsyncDelegateCommand(OnConnect); + DisconnectCommand = new DelegateCommand(OnDisconnect); + CloseCommand = new DelegateCommand(OnClose); + SetVoltageLevelLowCommand = new AsyncDelegateCommand(OnSetVoltageLevelLow); + SetVoltageLevelHighCommand = new AsyncDelegateCommand(OnSetVoltageLevelHigh); + SetThreePhaseVoltageCommand = new AsyncDelegateCommand(OnSetThreePhaseVoltage); + SetCommonOutputVoltageCommand = new AsyncDelegateCommand(OnSetCommonOutputVoltage); + SetCommonOutputFrequencyCommand = new AsyncDelegateCommand(OnSetCommonOutputFrequency); + SetStepOutputVoltageCommand = new AsyncDelegateCommand(OnSetStepOutputVoltage); + SetStepOutputFrequencyCommand = new AsyncDelegateCommand(OnSetStepOutputFrequency); + ClosePowerSupplyCommand = new AsyncDelegateCommand(ClosePowerSupply); + OpenPowerSupplyCommand = new AsyncDelegateCommand(OpenPowerSupply); + } + + #region Command Handlers + private void OnClose() + { + RequestClose.Invoke(); + } + private async Task OnConnect() + { + await device.ConnectAsync(); + } + + private void OnDisconnect() + { + device.Close(); + } + private async Task OpenPowerSupply() + { + await device.启动电源(); + } + + private async Task ClosePowerSupply() + { + await device.关闭电源(); + } + private async Task OnSetVoltageLevelLow() + { + + } + + private async Task OnSetVoltageLevelHigh() + { + + } + + private async Task OnSetThreePhaseVoltage() + { + + } + + private async Task OnSetCommonOutputVoltage() + { + + } + + private async Task OnSetCommonOutputFrequency() + { + + } + + private async Task OnSetStepOutputVoltage() + { + + } + + private async Task OnSetStepOutputFrequency() + { + + } + + #endregion + + #region dialog规范 + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + try + { + var a = _devices.DeviceDic["SQ0030G1D"] as SQ0030G1D; + if (a != null) + { + device = a; + } + else + { + LoggerHelper.ErrorWithNotify("设备没有初始化无法打开测试界面"); + RequestClose.Invoke(); + } + } + catch (Exception) + { + LoggerHelper.ErrorWithNotify("找不到设备无法打开测试界面"); + } + + } + + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/WS-68030-380TViewModel.cs b/BOB/ViewModels/Dialogs/WS-68030-380TViewModel.cs new file mode 100644 index 0000000..6f3e2bb --- /dev/null +++ b/BOB/ViewModels/Dialogs/WS-68030-380TViewModel.cs @@ -0,0 +1,149 @@ +using BOB.Singleton; +using DeviceCommand.Device; +using Logger; +using NetTaste; +using Prism.Commands; +using Prism.Mvvm; +using System; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace BOB.ViewModels.Dialogs +{ + public class WS_68030_380TViewModel : BindableBase, IDialogAware + { + #region 属性 + + private string _title = "交流负载"; + public string Title + { + get { return _title; } + set { SetProperty(ref _title, value); } + } + + private string _currentPowerDisplay; + public string CurrentPowerDisplay + { + get { return _currentPowerDisplay; } + set { SetProperty(ref _currentPowerDisplay, value); } + } + + #endregion + + #region 命令 + + public ICommand ConnectCommand { get; private set; } + public ICommand DisconnectCommand { get; private set; } + public ICommand LoadCommand { get; private set; } + public ICommand UnloadCommand { get; private set; } + public ICommand ReadPowerCommand { get; private set; } + public ICommand SetPowerCommand { get; private set; } + public ICommand CloseCommand { get; private set; } + + #endregion + + #region 事件聚合器和设备操作 + + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + private WS_68030_380T device { get; set; } + + public WS_68030_380TViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + + // 初始化命令 + ConnectCommand = new AsyncDelegateCommand(OnConnect); + DisconnectCommand = new DelegateCommand(OnDisconnect); + LoadCommand = new AsyncDelegateCommand(OnLoad); + UnloadCommand = new AsyncDelegateCommand(OnUnload); + ReadPowerCommand = new AsyncDelegateCommand(OnReadPower); + SetPowerCommand = new AsyncDelegateCommand(OnSetPower); + CloseCommand = new DelegateCommand(OnClose); + } + + #endregion + + #region 命令处理方法 + + private async Task OnConnect() + { + await device.ConnectAsync(); + } + + private void OnDisconnect() + { + device.Close(); + } + + private async Task OnLoad() + { + await device.加载(); + } + + private async Task OnUnload() + { + await device.卸载(); + } + + private async Task OnReadPower() + { + var result = await device.读取功率_KW(); + } + + private async Task OnSetPower() + { + if (float.TryParse(CurrentPowerDisplay, out float a)) + { + await device.设置功率_KW(a); + } + } + + #endregion + + #region Dialog 规范 + + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + try + { + var a = _devices.DeviceDic["WS_68030_380T"] as WS_68030_380T; + if (a != null) + { + device = a; + } + else + { + LoggerHelper.ErrorWithNotify("设备没有初始化无法打开测试界面"); + RequestClose.Invoke(); + } + } + catch (Exception) + { + LoggerHelper.ErrorWithNotify("找不到设备无法打开测试界面"); + } + + } + private void OnClose() + { + RequestClose.Invoke(); + } + + #endregion + } +} diff --git a/BOB/ViewModels/Dialogs/ZXKSViewModel.cs b/BOB/ViewModels/Dialogs/ZXKSViewModel.cs new file mode 100644 index 0000000..f2cadce --- /dev/null +++ b/BOB/ViewModels/Dialogs/ZXKSViewModel.cs @@ -0,0 +1,57 @@ +using BOB.Singleton; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BOB.ViewModels.Dialogs +{ + public class ZXKSViewModel : BindableBase, IDialogAware + { + + #region 属性 + private string _Title = "环境箱"; + + public string Title + { + get { return _Title; } + set { SetProperty(ref _Title, value); } + } + + + #endregion + #region 命令 + + + #endregion + private IEventAggregator _eventAggregator { get; set; } + private Devices _devices { get; set; } + private GlobalVariables _globalVariables { get; set; } + public ZXKSViewModel(IContainerProvider containerProvider) + { + _devices = containerProvider.Resolve(); + _globalVariables = containerProvider.Resolve(); + _eventAggregator = containerProvider.Resolve(); + } + + #region dialog规范 + public DialogCloseListener RequestClose { get; set; } + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + + } + + public void OnDialogOpened(IDialogParameters parameters) + { + + } + #endregion + } +} diff --git a/BOB/ViewModels/ParametersManagerViewModel.cs b/BOB/ViewModels/ParametersManagerViewModel.cs index ff0ae01..e0d34af 100644 --- a/BOB/ViewModels/ParametersManagerViewModel.cs +++ b/BOB/ViewModels/ParametersManagerViewModel.cs @@ -1,11 +1,14 @@ using BOB.Models; using BOB.Singleton; +using BOB.Views.Dialogs; using Common.PubEvent; using DeviceCommand.Base; using DeviceCommand.Device; using Logger; using MaterialDesignThemes.Wpf; using Model; +using OxyPlot; +using Prism.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -13,6 +16,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; +using System.Windows; using System.Windows.Input; using System.Xml; @@ -69,6 +73,7 @@ namespace BOB.ViewModels #endregion private GlobalVariables _globalVariables { get; set; } private IDialogService _dialogService { get; set; } + private IContainerProvider _containerProvider { get; set; } private Devices _devices { get; set; } private IEventAggregator _eventAggregator { get; set; } public ICommand ParameterAddCommand { get; set; } @@ -76,11 +81,13 @@ namespace BOB.ViewModels public ICommand ParameterDeleteCommand { get; set; } public ICommand DeviceEditCommand { get; set; } public ICommand ReconnnectCommand { get; set; } + public ICommand CloseCommand { get; set; } public ParametersManagerViewModel(GlobalVariables GlobalVariables,IDialogService dialogService,IEventAggregator eventAggregator,IContainerProvider containerProvider) { + _containerProvider= containerProvider; _globalVariables = GlobalVariables; _eventAggregator= eventAggregator; _devices=containerProvider.Resolve(); @@ -91,36 +98,12 @@ namespace BOB.ViewModels ParameterDeleteCommand = new DelegateCommand(ParameterDelete); DeviceEditCommand = new DelegateCommand(DeviceEdit); ReconnnectCommand = new DelegateCommand(Reconnnect); + CloseCommand = new DelegateCommand(Close); DeviceList = new ObservableCollection(SystemConfig.Instance.DeviceList); InitData(); } - private void Reconnnect() - { - if(SelectedDevice!=null) - { - if (_devices.DeviceDic.TryGetValue(SelectedDevice.Remark, out var device) && device != null) - { - Task.Run(async () => - { - switch (device) - { - case ITcp tcpDevice: - await tcpDevice.ConnectAsync(); - break; - - case ISerialPort serialDevice: - await serialDevice.ConnectAsync(); - break; - - case IModbusDevice modbusDevice: - await modbusDevice.ConnectAsync(); - break; - } - }); - } - } - } + private void InitData() { @@ -171,6 +154,27 @@ namespace BOB.ViewModels case IModbusDevice modbusDevice: isConnected = (modbusDevice.TcpClient?.Connected ?? false) || (modbusDevice.SerialPort?.IsOpen ?? false); break; + default: + if (device is Backfeed backfeed) + { + if (backfeed.CurrentDevice == "E36233A") + { + var e36233A = backfeed.CurrentInstance as E36233A; + if (e36233A != null) + { + isConnected = e36233A.TcpClient?.Connected ?? false; + } + } + else if (backfeed.CurrentDevice == "IT6724CReverse") + { + var it6724CReverse = backfeed.CurrentInstance as IT6724CReverse; + if (it6724CReverse != null) + { + isConnected = it6724CReverse.SerialPort?.IsOpen ?? false; + } + } + } + break; } } @@ -193,21 +197,15 @@ namespace BOB.ViewModels { return; } - var param = new DialogParameters + var type = SelectedDevice.DeviceType.Split('.').Last(); + if(type=="E36233A"|| type == "IT6724CReverse") { - { "Devices", SelectedDevice } - }; - _dialogService.ShowDialog("DeviceSetting", param, (r) => + _dialogService.Show("Backfeed"); + } + else { - if (r.Result == ButtonResult.OK) - { - - } - else - { - - } - }); + _dialogService.Show(type); + } } private void ParameterDelete() @@ -254,7 +252,113 @@ namespace BOB.ViewModels }); } + private void Close() + { + if (SelectedDevice != null) + { + if (_devices.DeviceDic.TryGetValue(SelectedDevice.Remark, out var device) && device != null) + { + Task.Run(() => + { + switch (device) + { + case ITcp tcpDevice: + tcpDevice.Close(); + break; + + case ISerialPort serialDevice: + serialDevice.Close(); + break; + + case IModbusDevice modbusDevice: + modbusDevice.Close(); + break; + default: + if (device is Backfeed backfeed) + { + if (backfeed.CurrentDevice == "E36233A") + { + var e36233A = backfeed.CurrentInstance as E36233A; + if (e36233A != null) + { + e36233A.Close(); + } + } + else if (backfeed.CurrentDevice == "IT6724CReverse") + { + var it6724CReverse = backfeed.CurrentInstance as IT6724CReverse; + if (it6724CReverse != null) + { + it6724CReverse.Close(); + } + } + } + break; + + } + }); + } + } + } + + private void Reconnnect() + { + if (SelectedDevice != null) + { + if (_devices.DeviceDic.TryGetValue(SelectedDevice.Remark, out var device) && device != null) + { + Task.Run(async () => + { + try + { + switch (device) + { + case ITcp tcpDevice: + await tcpDevice.ConnectAsync(); + + break; + + case ISerialPort serialDevice: + await serialDevice.ConnectAsync(); + break; + + case IModbusDevice modbusDevice: + await modbusDevice.ConnectAsync(); + break; + + default: + if (device is Backfeed backfeed) + { + if (backfeed.CurrentDevice == "E36233A") + { + var e36233A = backfeed.CurrentInstance as E36233A; + if (e36233A != null) + { + await e36233A.ConnectAsync(); + } + } + else if (backfeed.CurrentDevice == "IT6724CReverse") + { + var it6724CReverse = backfeed.CurrentInstance as IT6724CReverse; + if (it6724CReverse != null) + { + await it6724CReverse.ConnectAsync(); + } + } + } + break; + } + } + catch (Exception ex) + { + LoggerHelper.ErrorWithNotify($"设备重连时发生错误: {SelectedDevice.Remark} - {ex.Message}", ex.StackTrace); + } + }); + } + } + } + #endregion - + } } diff --git a/BOB/ViewModels/UserControls/NumericalDisplayViewModel.cs b/BOB/ViewModels/UserControls/NumericalDisplayViewModel.cs new file mode 100644 index 0000000..11a9edd --- /dev/null +++ b/BOB/ViewModels/UserControls/NumericalDisplayViewModel.cs @@ -0,0 +1,69 @@ +using Prism.Mvvm; +using System.Windows; +using System.Windows.Media; + +namespace BOB.ViewModels.UserControls +{ + public class NumericalDisplayViewModel : BindableBase + { + public NumericalDisplayViewModel() + { + + } + private string _channelNumber = string.Empty; + private double _MonitorValue = double.NaN; + private double _upperLimit = double.NaN; + private double _lowerLimit = double.NaN; + private SolidColorBrush _textColor = Brushes.Green; + private SolidColorBrush _backgroundColor = Brushes.White; + private Visibility _limitsVisibility = Visibility.Visible; + + // 通道号 + public string ChannelNumber + { + get => _channelNumber; + set => SetProperty(ref _channelNumber, value); + } + + public double MonitorValue + { + get => _MonitorValue; + set => SetProperty(ref _MonitorValue, value); + } + + // 上限 + public double UpperLimit + { + get => _upperLimit; + set => SetProperty(ref _upperLimit, value); + } + + // 下限 + public double LowerLimit + { + get => _lowerLimit; + set => SetProperty(ref _lowerLimit, value); + } + + // 文字颜色 + public SolidColorBrush TextColor + { + get => _textColor; + set => SetProperty(ref _textColor, value); + } + + // 背景颜色 + public SolidColorBrush BackgroundColor + { + get => _backgroundColor; + set => SetProperty(ref _backgroundColor, value); + } + + // 上下限可见度 + public Visibility LimitsVisibility + { + get => _limitsVisibility; + set => SetProperty(ref _limitsVisibility, value); + } + } +} diff --git a/BOB/Views/Dialogs/BackfeedView.xaml b/BOB/Views/Dialogs/BackfeedView.xaml new file mode 100644 index 0000000..0901294 --- /dev/null +++ b/BOB/Views/Dialogs/BackfeedView.xaml @@ -0,0 +1,216 @@ + + +