进程管理ui优化
This commit is contained in:
parent
9264596831
commit
ace97f14a6
@ -51,6 +51,7 @@ namespace BOB
|
|||||||
containerRegistry.RegisterForNavigation<MainView>("MainView");
|
containerRegistry.RegisterForNavigation<MainView>("MainView");
|
||||||
containerRegistry.RegisterForNavigation<MonitorView>("MonitorView");
|
containerRegistry.RegisterForNavigation<MonitorView>("MonitorView");
|
||||||
containerRegistry.RegisterForNavigation<Views.DataView>("DataView");
|
containerRegistry.RegisterForNavigation<Views.DataView>("DataView");
|
||||||
|
containerRegistry.RegisterForNavigation<UpdateInfoView>("UpdateInfoView");
|
||||||
//注册弹窗
|
//注册弹窗
|
||||||
containerRegistry.RegisterDialog<MessageBoxView, MessageBoxViewModel>("MessageBox");
|
containerRegistry.RegisterDialog<MessageBoxView, MessageBoxViewModel>("MessageBox");
|
||||||
containerRegistry.RegisterDialog<ParameterSetting, ParameterSettingViewModel>("ParameterSetting");
|
containerRegistry.RegisterDialog<ParameterSetting, ParameterSettingViewModel>("ParameterSetting");
|
||||||
|
|||||||
46
BOB/Services/BackfeedPollingRead.cs
Normal file
46
BOB/Services/BackfeedPollingRead.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.CodeDom;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class BackfeedPollingRead : PollingRead
|
||||||
|
{
|
||||||
|
private Backfeed _Backfeed { get;set; }
|
||||||
|
private IEventAggregator _eventAggregator { get;set; }
|
||||||
|
public BackfeedPollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "Backfeed";
|
||||||
|
_Backfeed = _devices.DeviceDic["Backfeed"]as Backfeed;
|
||||||
|
}
|
||||||
|
public double 实时电流 { get; set; } = double.NaN;
|
||||||
|
public double 实时电压 { get; set; } = double.NaN;
|
||||||
|
public double 实时功率 { get; set; } = double.NaN;
|
||||||
|
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
实时电流 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时电压 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时功率 = Random.Shared.NextDouble() * 10;
|
||||||
|
//实时电流 =await _Backfeed!.查询实时电流(ct);
|
||||||
|
//实时电压 = await _Backfeed!.查询实时电压(ct);
|
||||||
|
//实时功率 = await _Backfeed!.查询实时功率(ct);
|
||||||
|
var datalist = new List<double>() { 实时电流, 实时电压, 实时功率 };
|
||||||
|
var dataDic = new Dictionary<string, double>
|
||||||
|
{
|
||||||
|
{ "实时电流", 实时电流 },
|
||||||
|
{ "实时电压", 实时电压 },
|
||||||
|
{ "实时功率", 实时功率 }
|
||||||
|
};
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Publish(("Backfeed", dataDic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
BOB/Services/EAEL9080PollingRead.cs
Normal file
43
BOB/Services/EAEL9080PollingRead.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class EAEL9080PollingRead:PollingRead
|
||||||
|
{
|
||||||
|
private EAEL9080 _EAEL9080 { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public EAEL9080PollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "EAEL9080";
|
||||||
|
_EAEL9080 = _devices.DeviceDic["EAEL9080"] as EAEL9080;
|
||||||
|
}
|
||||||
|
public double 实时电流 { get; set; } = double.NaN;
|
||||||
|
public double 实时电压 { get; set; } = double.NaN;
|
||||||
|
public double 实时功率 { get; set; } = double.NaN;
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
实时电流 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时电压 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时功率 = Random.Shared.NextDouble() * 10;
|
||||||
|
//实时电流 = await _EAEL9080!.查询电流(ct);
|
||||||
|
//实时电压 = await _EAEL9080!.查询电压(ct);
|
||||||
|
//实时功率 = await _EAEL9080!.查询功率(ct);
|
||||||
|
var dataDic = new Dictionary<string, double>
|
||||||
|
{
|
||||||
|
{ "实时电流", 实时电流 },
|
||||||
|
{ "实时电压", 实时电压 },
|
||||||
|
{ "实时功率", 实时功率 }
|
||||||
|
};
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Publish(("EAEL9080", dataDic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
BOB/Services/IT6724CPollingRead.cs
Normal file
43
BOB/Services/IT6724CPollingRead.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class IT6724CPollingRead : PollingRead
|
||||||
|
{
|
||||||
|
private IT6724C _IT6724C { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public IT6724CPollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "Backfeed";
|
||||||
|
_IT6724C = _devices.DeviceDic["IT6724C"] as IT6724C;
|
||||||
|
}
|
||||||
|
public double 实时电流 { get; set; } = double.NaN;
|
||||||
|
public double 实时电压 { get; set; } = double.NaN;
|
||||||
|
public double 实时功率 { get; set; } = double.NaN;
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
实时电流 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时电压 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时功率 = Random.Shared.NextDouble() * 10;
|
||||||
|
//实时电流 = await _IT6724C!.查询实时电流(ct);
|
||||||
|
//实时电压 = await _IT6724C!.查询实时电压(ct);
|
||||||
|
//实时功率 = await _IT6724C!.查询实时功率(ct);
|
||||||
|
var dataDic = new Dictionary<string, double>
|
||||||
|
{
|
||||||
|
{ "实时电流", 实时电流 },
|
||||||
|
{ "实时电压", 实时电压 },
|
||||||
|
{ "实时功率", 实时功率 }
|
||||||
|
};
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Publish(("IT6724C", dataDic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
BOB/Services/LQ7500-DPollingRead.cs
Normal file
41
BOB/Services/LQ7500-DPollingRead.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class LQ7500_DPollingRead : PollingRead
|
||||||
|
{
|
||||||
|
private LQ7500_D _LQ7500_D { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public LQ7500_DPollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "LQ7500_D";
|
||||||
|
_LQ7500_D = _devices.DeviceDic["LQ7500_D"] as LQ7500_D;
|
||||||
|
}
|
||||||
|
public double 内部传感器温度 { get; set; } = double.NaN;
|
||||||
|
public double 外部传感器温度 { get; set; } = double.NaN;
|
||||||
|
public double 水流量 { get; set; } = double.NaN;
|
||||||
|
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
内部传感器温度 = await _LQ7500_D.读取内部传感器温度();
|
||||||
|
外部传感器温度 = await _LQ7500_D.读取外部传感器温度();
|
||||||
|
水流量 = await _LQ7500_D.读取流量();
|
||||||
|
var dataDic = new Dictionary<string, double>
|
||||||
|
{
|
||||||
|
{ "内部传感器温度", 内部传感器温度 },
|
||||||
|
{ "外部传感器温度", 外部传感器温度 },
|
||||||
|
{ "水流量", 水流量 }
|
||||||
|
};
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Publish(("LQ7500_D", dataDic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
BOB/Services/PSB11000PollingRead.cs
Normal file
46
BOB/Services/PSB11000PollingRead.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class PSB11000PollingRead : PollingRead
|
||||||
|
{
|
||||||
|
private PSB11000 _PSB11000 { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public PSB11000PollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "PSB11000";
|
||||||
|
_PSB11000 = _devices.DeviceDic["PSB11000"] as PSB11000;
|
||||||
|
}
|
||||||
|
public double 实时电流 { get; set; } = double.NaN;
|
||||||
|
public double 实时电压 { get; set; } = double.NaN;
|
||||||
|
public double 实时功率 { get; set; } = double.NaN;
|
||||||
|
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
|
||||||
|
实时电流 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时电压 = Random.Shared.NextDouble() * 10;
|
||||||
|
实时功率 = Random.Shared.NextDouble() * 10;
|
||||||
|
//实时电流 = await _PSB11000!.查询电流(ct);
|
||||||
|
//实时电压 = await _PSB11000!.查询电压(ct);
|
||||||
|
//实时功率 = await _PSB11000!.查询功率(ct);
|
||||||
|
var datalist = new List<double>() { 实时电流, 实时电压, 实时功率 };
|
||||||
|
var dataDic = new Dictionary<string, double>
|
||||||
|
{
|
||||||
|
{ "实时电流", 实时电流 },
|
||||||
|
{ "实时电压", 实时电压 },
|
||||||
|
{ "实时功率", 实时功率 }
|
||||||
|
};
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Publish(("PSB11000", dataDic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
BOB/Services/PollingRead.cs
Normal file
75
BOB/Services/PollingRead.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using BOB.Converters;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public abstract class PollingRead
|
||||||
|
{
|
||||||
|
private CancellationTokenSource _pollingCancellationTokenSource;
|
||||||
|
private Task? _pollingTask;
|
||||||
|
public int PollingInterval = 1000;
|
||||||
|
public string DeviceName{get;set;}="";
|
||||||
|
private bool IsConnect{ get; set; }=false;
|
||||||
|
public PollingRead(IContainerProvider containerProvider)
|
||||||
|
{
|
||||||
|
var _eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
_eventAggregator.GetEvent<ConnectionChangeEvent>().Subscribe(PollingConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PollingConnection((string, bool) tuple)
|
||||||
|
{
|
||||||
|
var (device, isConnect) = tuple;
|
||||||
|
//System.Diagnostics.Debug.WriteLine($"PollingRead收到连接状态变化事件:设备={device},状态={isConnect}");
|
||||||
|
if (device== DeviceName)
|
||||||
|
{
|
||||||
|
IsConnect = isConnect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartPolling()
|
||||||
|
{
|
||||||
|
if (_pollingTask != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_pollingCancellationTokenSource == null || _pollingCancellationTokenSource.IsCancellationRequested)
|
||||||
|
_pollingCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
_pollingTask = Task.Run(() => PollingLoop(_pollingCancellationTokenSource.Token));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopPolling()
|
||||||
|
{
|
||||||
|
_pollingCancellationTokenSource?.Cancel();
|
||||||
|
_pollingTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task PollingLoop(CancellationToken ct)
|
||||||
|
{
|
||||||
|
while (!ct.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
if (IsConnect)
|
||||||
|
{
|
||||||
|
await Task.Delay(PollingInterval, ct);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ReadDeviceDataAsync(ct);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"轮询过程中发生错误: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public abstract Task ReadDeviceDataAsync(CancellationToken ct = default);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
32
BOB/Services/SQ0030G1DPollingRead.cs
Normal file
32
BOB/Services/SQ0030G1DPollingRead.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class SQ0030G1DPollingRead : PollingRead
|
||||||
|
{
|
||||||
|
private SQ0030G1D _SQ0030G1D { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public SQ0030G1DPollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "SQ0030G1D";
|
||||||
|
_SQ0030G1D = _devices.DeviceDic["SQ0030G1D"] as SQ0030G1D;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
BOB/Services/WS-68030-380TPollingRead.cs
Normal file
30
BOB/Services/WS-68030-380TPollingRead.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class WS_68030_380TPollingRead : PollingRead
|
||||||
|
{
|
||||||
|
private WS_68030_380T _WS_68030_380T { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public WS_68030_380TPollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "WS_68030_380T";
|
||||||
|
_WS_68030_380T = _devices.DeviceDic["WS_68030_380T"] as WS_68030_380T;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
BOB/Services/ZXKSPollingRead.cs
Normal file
32
BOB/Services/ZXKSPollingRead.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BOB.Services
|
||||||
|
{
|
||||||
|
public class ZXKSPollingRead : PollingRead
|
||||||
|
{
|
||||||
|
private ZXKS _ZXKS { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public ZXKSPollingRead(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
var _devices = containerProvider.Resolve<Devices>();
|
||||||
|
DeviceName = "ZXKS";
|
||||||
|
_ZXKS = _devices.DeviceDic["ZXKS"] as ZXKS;
|
||||||
|
}
|
||||||
|
public double 实时电流 { get; set; } = double.NaN;
|
||||||
|
public double 实时电压 { get; set; } = double.NaN;
|
||||||
|
public double 实时功率 { get; set; } = double.NaN;
|
||||||
|
|
||||||
|
public override async Task ReadDeviceDataAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using Castle.DynamicProxy;
|
using BOB.Services;
|
||||||
|
using Castle.DynamicProxy;
|
||||||
using DeviceCommand.Base;
|
using DeviceCommand.Base;
|
||||||
using DeviceCommand.Device;
|
using DeviceCommand.Device;
|
||||||
using Logger;
|
using Logger;
|
||||||
@ -13,10 +14,16 @@ namespace BOB.Singleton
|
|||||||
{
|
{
|
||||||
public class Devices
|
public class Devices
|
||||||
{
|
{
|
||||||
|
public Devices(IContainerProvider containerProvider)
|
||||||
|
{
|
||||||
|
_containerProvider=containerProvider;
|
||||||
|
}
|
||||||
|
private IContainerProvider _containerProvider;
|
||||||
private CancellationTokenSource _appCancellationTokenSource = new();
|
private CancellationTokenSource _appCancellationTokenSource = new();
|
||||||
public CancellationToken AppCancellationToken => _appCancellationTokenSource.Token;
|
public CancellationToken AppCancellationToken => _appCancellationTokenSource.Token;
|
||||||
|
|
||||||
public Dictionary<string, object> DeviceDic { get; private set; } = new Dictionary<string, object>();
|
public Dictionary<string, object> DeviceDic { get; private set; } = new Dictionary<string, object>();
|
||||||
|
public Dictionary<string, PollingRead> PollingReadDic { get; private set; } = new Dictionary<string, PollingRead>();
|
||||||
|
|
||||||
private readonly ProxyGenerator _proxyGen = new ProxyGenerator();
|
private readonly ProxyGenerator _proxyGen = new ProxyGenerator();
|
||||||
private readonly IInterceptor _loggingInterceptor = new LoggingInterceptor();
|
private readonly IInterceptor _loggingInterceptor = new LoggingInterceptor();
|
||||||
@ -31,15 +38,11 @@ namespace BOB.Singleton
|
|||||||
private IModbusDevice ZXKSTDevice { get; set; }
|
private IModbusDevice ZXKSTDevice { get; set; }
|
||||||
private Backfeed BackfeedDevice { get; set; }
|
private Backfeed BackfeedDevice { get; set; }
|
||||||
|
|
||||||
public Devices()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public void Init(List<DeviceConfigModel> deviceList)
|
public void Init(List<DeviceConfigModel> deviceList)
|
||||||
{
|
{
|
||||||
foreach (var device in deviceList)
|
foreach (var device in deviceList)
|
||||||
{
|
{
|
||||||
if (!device.IsEnabled) continue;
|
if (!device.IsEnabled) continue;
|
||||||
|
|
||||||
switch (device.DeviceType)
|
switch (device.DeviceType)
|
||||||
{
|
{
|
||||||
case "DeviceCommand.Device.E36233A":
|
case "DeviceCommand.Device.E36233A":
|
||||||
@ -235,6 +238,86 @@ namespace BOB.Singleton
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void StartPollingCollectionAsync()
|
||||||
|
{
|
||||||
|
foreach (var dc in DeviceDic)
|
||||||
|
{
|
||||||
|
var name = dc.Key;
|
||||||
|
|
||||||
|
switch (name)
|
||||||
|
{
|
||||||
|
case "Backfeed":
|
||||||
|
{
|
||||||
|
var polling = new BackfeedPollingRead(_containerProvider);
|
||||||
|
PollingReadDic.Add("Backfeed", polling);
|
||||||
|
polling.StartPolling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "IT6724C":
|
||||||
|
{
|
||||||
|
var polling = new IT6724CPollingRead(_containerProvider);
|
||||||
|
PollingReadDic.Add("IT6724C", polling);
|
||||||
|
polling.StartPolling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "LQ7500_D":
|
||||||
|
{
|
||||||
|
var polling = new LQ7500_DPollingRead(_containerProvider);
|
||||||
|
PollingReadDic.Add("LQ7500_D", polling);
|
||||||
|
polling.StartPolling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "EAEL9080":
|
||||||
|
{
|
||||||
|
var polling = new EAEL9080PollingRead(_containerProvider);
|
||||||
|
PollingReadDic.Add("EAEL9080", polling);
|
||||||
|
polling.StartPolling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "IOBoard":
|
||||||
|
{
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "PSB11000":
|
||||||
|
{
|
||||||
|
var polling = new PSB11000PollingRead(_containerProvider);
|
||||||
|
PollingReadDic.Add("PSB11000", polling);
|
||||||
|
polling.StartPolling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "WS_68030_380T":
|
||||||
|
{
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "SQ0030G1D":
|
||||||
|
{
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "ZXKS":
|
||||||
|
{
|
||||||
|
var polling = new ZXKSPollingRead(_containerProvider);
|
||||||
|
PollingReadDic.Add("ZXKS", polling);
|
||||||
|
polling.StartPolling();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
LoggerHelper.Warn($"未定义 {name} 的轮询处理器");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
using BOB.Models;
|
using BOB.Models;
|
||||||
using Logger;
|
using Logger;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Model;
|
using Model;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ namespace BOB
|
|||||||
public string SubProgramFilePath { get; set; } = @"D:\BOB\子程序\";
|
public string SubProgramFilePath { get; set; } = @"D:\BOB\子程序\";
|
||||||
|
|
||||||
public string DefaultSubProgramFilePath { get; set; } = "";
|
public string DefaultSubProgramFilePath { get; set; } = "";
|
||||||
|
public ObservableCollection<string> CurSingleList { get; set; }
|
||||||
public List<DeviceConfigModel> DeviceList { get; set; } = new();
|
public List<DeviceConfigModel> DeviceList { get; set; } = new();
|
||||||
|
|
||||||
#region 配置加载方法
|
#region 配置加载方法
|
||||||
|
|||||||
@ -1,159 +0,0 @@
|
|||||||
using DeviceCommand.Base;
|
|
||||||
using DeviceCommand.Device;
|
|
||||||
using Logger;
|
|
||||||
|
|
||||||
|
|
||||||
namespace BOB.Tasks
|
|
||||||
{
|
|
||||||
public class HeartbeatManager<T> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,12 @@
|
|||||||
using BOB.Singleton;
|
using BOB.Singleton;
|
||||||
|
using BOB.ViewModels.UserControls;
|
||||||
|
using Common.PubEvent;
|
||||||
using DeviceCommand.Device;
|
using DeviceCommand.Device;
|
||||||
using Logger;
|
using Logger;
|
||||||
|
using OxyPlot;
|
||||||
|
using OxyPlot.Axes;
|
||||||
|
using OxyPlot.Legends;
|
||||||
|
using OxyPlot.Series;
|
||||||
using Prism.Commands;
|
using Prism.Commands;
|
||||||
using Prism.Events;
|
using Prism.Events;
|
||||||
using Prism.Mvvm;
|
using Prism.Mvvm;
|
||||||
@ -62,7 +68,54 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
get { return _OPP功率; }
|
get { return _OPP功率; }
|
||||||
set { SetProperty(ref _OPP功率, value); }
|
set { SetProperty(ref _OPP功率, value); }
|
||||||
}
|
}
|
||||||
|
private LineSeries _电压_lineSeries = new LineSeries { Title = "电压(V)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 电压_lineSeries
|
||||||
|
{
|
||||||
|
get => _电压_lineSeries;
|
||||||
|
set => SetProperty(ref _电压_lineSeries, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineSeries _电流_lineSeries = new LineSeries { Title = "电流(A)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 电流_lineSeries
|
||||||
|
{
|
||||||
|
get => _电流_lineSeries;
|
||||||
|
set => SetProperty(ref _电流_lineSeries, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineSeries _功率_lineSeries = new LineSeries { Title = "功率(W)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 功率_lineSeries
|
||||||
|
{
|
||||||
|
get => _功率_lineSeries;
|
||||||
|
set => SetProperty(ref _功率_lineSeries, value);
|
||||||
|
}
|
||||||
|
private NumericalDisplayViewModel _电压MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 电压MV
|
||||||
|
{
|
||||||
|
get => _电压MV;
|
||||||
|
set => SetProperty(ref _电压MV, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NumericalDisplayViewModel _电流MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 电流MV
|
||||||
|
{
|
||||||
|
get => _电流MV;
|
||||||
|
set => SetProperty(ref _电流MV, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NumericalDisplayViewModel _功率MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 功率MV
|
||||||
|
{
|
||||||
|
get => _功率MV;
|
||||||
|
set => SetProperty(ref _功率MV, value);
|
||||||
|
}
|
||||||
|
private PlotModel _曲线Model = new PlotModel();
|
||||||
|
public PlotModel 曲线Model
|
||||||
|
{
|
||||||
|
get => _曲线Model;
|
||||||
|
set => SetProperty(ref _曲线Model, value);
|
||||||
|
}
|
||||||
|
public DateTimeAxis TimeAxis { get; private set; }
|
||||||
|
public LinearAxis ValueAxis { get; private set; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 命令
|
#region 命令
|
||||||
@ -82,6 +135,7 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
public ICommand DisableOPPCommand { get; private set; }
|
public ICommand DisableOPPCommand { get; private set; }
|
||||||
public ICommand SetOPPCommand { get; private set; }
|
public ICommand SetOPPCommand { get; private set; }
|
||||||
public ICommand CloseCommand { get; private set; }
|
public ICommand CloseCommand { get; private set; }
|
||||||
|
public ICommand ResetViewCommand { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -113,6 +167,55 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
DisableOPPCommand = new AsyncDelegateCommand(OnDisableOPP);
|
DisableOPPCommand = new AsyncDelegateCommand(OnDisableOPP);
|
||||||
SetOPPCommand = new AsyncDelegateCommand(OnSetOPP);
|
SetOPPCommand = new AsyncDelegateCommand(OnSetOPP);
|
||||||
CloseCommand = new DelegateCommand(OnClose);
|
CloseCommand = new DelegateCommand(OnClose);
|
||||||
|
ResetViewCommand = new DelegateCommand(ResetView);
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Subscribe(UpdateCurve);
|
||||||
|
InitCurve();
|
||||||
|
}
|
||||||
|
private void ResetView()
|
||||||
|
{
|
||||||
|
曲线Model.ResetAllAxes();
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
|
private void InitCurve()
|
||||||
|
{
|
||||||
|
TimeAxis = new DateTimeAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Bottom,
|
||||||
|
StringFormat = "HH:mm:ss",
|
||||||
|
IntervalType = DateTimeIntervalType.Seconds,
|
||||||
|
};
|
||||||
|
ValueAxis = new LinearAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Left,
|
||||||
|
};
|
||||||
|
曲线Model.Axes.Add(TimeAxis);
|
||||||
|
曲线Model.Axes.Add(ValueAxis);
|
||||||
|
曲线Model.Series.Add(电压_lineSeries);
|
||||||
|
曲线Model.Series.Add(电流_lineSeries);
|
||||||
|
曲线Model.Series.Add(功率_lineSeries);
|
||||||
|
曲线Model.Legends.Add(new Legend()
|
||||||
|
{
|
||||||
|
LegendPosition = LegendPosition.TopRight,
|
||||||
|
LegendOrientation = LegendOrientation.Vertical,
|
||||||
|
LegendPlacement = LegendPlacement.Inside
|
||||||
|
});
|
||||||
|
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCurve((string device, Dictionary<string, double> data )tuple)
|
||||||
|
{
|
||||||
|
var (device, data) = tuple;
|
||||||
|
if (device != "IT6724C") return;
|
||||||
|
电流MV.MonitorValue = data["实时电流"];
|
||||||
|
电压MV.MonitorValue = data["实时电压"];
|
||||||
|
功率MV.MonitorValue = data["实时功率"];
|
||||||
|
|
||||||
|
var now = DateTimeAxis.ToDouble(DateTime.Now);
|
||||||
|
电流_lineSeries.Points.Add(new DataPoint(now, data["实时电流"]));
|
||||||
|
电压_lineSeries.Points.Add(new DataPoint(now, data["实时电压"]));
|
||||||
|
功率_lineSeries.Points.Add(new DataPoint(now, data["实时功率"]));
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,19 @@
|
|||||||
using BOB.Singleton;
|
using BOB.Singleton;
|
||||||
|
using BOB.ViewModels.UserControls;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using DeviceCommand.Device;
|
||||||
|
using Logger;
|
||||||
|
using OxyPlot;
|
||||||
|
using OxyPlot.Annotations;
|
||||||
|
using OxyPlot.Axes;
|
||||||
|
using OxyPlot.Legends;
|
||||||
|
using OxyPlot.Series;
|
||||||
using Prism.Commands;
|
using Prism.Commands;
|
||||||
using Prism.Mvvm;
|
|
||||||
using Prism.Events;
|
using Prism.Events;
|
||||||
|
using Prism.Mvvm;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using DeviceCommand.Device;
|
|
||||||
using Logger;
|
|
||||||
using BOB.ViewModels.UserControls;
|
|
||||||
|
|
||||||
namespace BOB.ViewModels.Dialogs
|
namespace BOB.ViewModels.Dialogs
|
||||||
{
|
{
|
||||||
@ -17,12 +23,31 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
private string _Title = "低压直流负载";
|
private string _Title = "低压直流负载";
|
||||||
private string _设备标识字符串;
|
private string _设备标识字符串;
|
||||||
private string _负载模式;
|
private string _负载模式;
|
||||||
private string _电流LA;
|
private LineSeries _电压_lineSeries = new LineSeries
|
||||||
private string _电流LB;
|
{
|
||||||
|
Title = "电压(V)",
|
||||||
|
StrokeThickness = 2,
|
||||||
|
};
|
||||||
|
private LineSeries _电流_lineSeries = new LineSeries
|
||||||
|
{
|
||||||
|
Title = "电流(A)",
|
||||||
|
StrokeThickness = 2,
|
||||||
|
};
|
||||||
|
private LineSeries _功率_lineSeries = new LineSeries
|
||||||
|
{
|
||||||
|
Title = "功率(W)",
|
||||||
|
StrokeThickness = 2,
|
||||||
|
};
|
||||||
private NumericalDisplayViewModel _电压MV=new();
|
private NumericalDisplayViewModel _电压MV=new();
|
||||||
private NumericalDisplayViewModel _电流MV = new();
|
private NumericalDisplayViewModel _电流MV = new();
|
||||||
private NumericalDisplayViewModel _功率MV=new();
|
private NumericalDisplayViewModel _功率MV=new();
|
||||||
|
private PlotModel _曲线Model = new();
|
||||||
|
|
||||||
|
public PlotModel 曲线Model
|
||||||
|
{
|
||||||
|
get { return _曲线Model; }
|
||||||
|
set { SetProperty(ref _曲线Model, value); }
|
||||||
|
}
|
||||||
public string Title
|
public string Title
|
||||||
{
|
{
|
||||||
get { return _Title; }
|
get { return _Title; }
|
||||||
@ -41,16 +66,21 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
set { SetProperty(ref _负载模式, value); }
|
set { SetProperty(ref _负载模式, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string 电流LA
|
public LineSeries 电流_lineSeries
|
||||||
{
|
{
|
||||||
get { return _电流LA; }
|
get { return _电流_lineSeries; }
|
||||||
set { SetProperty(ref _电流LA, value); }
|
set { SetProperty(ref _电流_lineSeries, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string 电流LB
|
public LineSeries 电压_lineSeries
|
||||||
{
|
{
|
||||||
get { return _电流LB; }
|
get { return _电压_lineSeries; }
|
||||||
set { SetProperty(ref _电流LB, value); }
|
set { SetProperty(ref _电压_lineSeries, value); }
|
||||||
|
}
|
||||||
|
public LineSeries 功率_lineSeries
|
||||||
|
{
|
||||||
|
get { return _功率_lineSeries; }
|
||||||
|
set { SetProperty(ref _功率_lineSeries, value); }
|
||||||
}
|
}
|
||||||
public NumericalDisplayViewModel 电压MV
|
public NumericalDisplayViewModel 电压MV
|
||||||
{
|
{
|
||||||
@ -67,6 +97,8 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
get { return _功率MV; }
|
get { return _功率MV; }
|
||||||
set { SetProperty(ref _功率MV, value); }
|
set { SetProperty(ref _功率MV, value); }
|
||||||
}
|
}
|
||||||
|
public DateTimeAxis TimeAxis { get; private set; }
|
||||||
|
public LinearAxis ValueAxis { get; private set; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 命令
|
#region 命令
|
||||||
@ -78,6 +110,7 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
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 ResetViewCommand { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -99,8 +132,56 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
电源输出关命令 = new AsyncDelegateCommand(OnPowerOff);
|
电源输出关命令 = new AsyncDelegateCommand(OnPowerOff);
|
||||||
关闭命令 = new DelegateCommand(OnOff);
|
关闭命令 = new DelegateCommand(OnOff);
|
||||||
查询设备信息命令 = new AsyncDelegateCommand(OnQueryDeviceInfo);
|
查询设备信息命令 = new AsyncDelegateCommand(OnQueryDeviceInfo);
|
||||||
|
ResetViewCommand = new DelegateCommand(ResetView);
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Subscribe(UpdateCurve);
|
||||||
|
InitCurve();
|
||||||
|
}
|
||||||
|
private void ResetView()
|
||||||
|
{
|
||||||
|
曲线Model.ResetAllAxes();
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
|
private void InitCurve()
|
||||||
|
{
|
||||||
|
TimeAxis = new DateTimeAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Bottom,
|
||||||
|
StringFormat = "HH:mm:ss",
|
||||||
|
IntervalType = DateTimeIntervalType.Seconds,
|
||||||
|
};
|
||||||
|
ValueAxis = new LinearAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Left,
|
||||||
|
};
|
||||||
|
曲线Model.Axes.Add(TimeAxis);
|
||||||
|
曲线Model.Axes.Add(ValueAxis);
|
||||||
|
曲线Model.Series.Add(电压_lineSeries);
|
||||||
|
曲线Model.Series.Add(电流_lineSeries);
|
||||||
|
曲线Model.Series.Add(功率_lineSeries);
|
||||||
|
曲线Model.Legends.Add(new Legend()
|
||||||
|
{
|
||||||
|
LegendPosition = LegendPosition.TopRight,
|
||||||
|
LegendOrientation = LegendOrientation.Vertical,
|
||||||
|
LegendPlacement = LegendPlacement.Inside
|
||||||
|
});
|
||||||
|
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateCurve((string device, Dictionary<string,double> data) tuple)
|
||||||
|
{
|
||||||
|
var (device, data) = tuple;
|
||||||
|
if (device != "EAEL9080") return;
|
||||||
|
电流MV.MonitorValue = data["实时电流"];
|
||||||
|
电压MV.MonitorValue = data["实时电压"];
|
||||||
|
功率MV.MonitorValue = data["实时功率"];
|
||||||
|
|
||||||
|
var now = DateTimeAxis.ToDouble(DateTime.Now);
|
||||||
|
电流_lineSeries.Points.Add(new DataPoint(now, data["实时电流"]));
|
||||||
|
电压_lineSeries.Points.Add(new DataPoint(now, data["实时电压"]));
|
||||||
|
功率_lineSeries.Points.Add(new DataPoint(now, data["实时功率"]));
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
private async Task OnQueryDeviceInfo()
|
private async Task OnQueryDeviceInfo()
|
||||||
{
|
{
|
||||||
设备标识字符串 = await device.查询设备信息();
|
设备标识字符串 = await device.查询设备信息();
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
using BOB.Singleton;
|
using BOB.Singleton;
|
||||||
|
using BOB.ViewModels.UserControls;
|
||||||
|
using Common.PubEvent;
|
||||||
using DeviceCommand.Device;
|
using DeviceCommand.Device;
|
||||||
using Logger;
|
using Logger;
|
||||||
|
using OxyPlot;
|
||||||
|
using OxyPlot.Annotations;
|
||||||
|
using OxyPlot.Axes;
|
||||||
|
using OxyPlot.Legends;
|
||||||
|
using OxyPlot.Series;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -12,52 +19,97 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
{
|
{
|
||||||
public class IT6724CViewModel : BindableBase, IDialogAware
|
public class IT6724CViewModel : BindableBase, IDialogAware
|
||||||
{
|
{
|
||||||
|
|
||||||
#region 属性
|
#region 属性
|
||||||
|
|
||||||
private string _title = "低压直流电源";
|
private string _title = "低压直流电源";
|
||||||
public string Title
|
public string Title
|
||||||
{
|
{
|
||||||
get { return _title; }
|
get => _title;
|
||||||
set { SetProperty(ref _title, value); }
|
set => SetProperty(ref _title, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _设备标识字符串;
|
private string _设备标识字符串;
|
||||||
public string 设备标识字符串
|
public string 设备标识字符串
|
||||||
{
|
{
|
||||||
get { return _设备标识字符串; }
|
get => _设备标识字符串;
|
||||||
set { SetProperty(ref _设备标识字符串, value); }
|
set => SetProperty(ref _设备标识字符串, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _输出电压;
|
private string _输出电压;
|
||||||
public string 输出电压
|
public string 输出电压
|
||||||
{
|
{
|
||||||
get { return _输出电压; }
|
get => _输出电压;
|
||||||
set { SetProperty(ref _输出电压, value); }
|
set => SetProperty(ref _输出电压, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _输出电流;
|
private string _输出电流;
|
||||||
public string 输出电流
|
public string 输出电流
|
||||||
{
|
{
|
||||||
get { return _输出电流; }
|
get => _输出电流;
|
||||||
set { SetProperty(ref _输出电流, value); }
|
set => SetProperty(ref _输出电流, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _OCP电流;
|
private string _OCP电流;
|
||||||
public string OCP电流
|
public string OCP电流
|
||||||
{
|
{
|
||||||
get { return _OCP电流; }
|
get => _OCP电流;
|
||||||
set { SetProperty(ref _OCP电流, value); }
|
set => SetProperty(ref _OCP电流, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _OVP电压;
|
private string _OVP电压;
|
||||||
public string OVP电压
|
public string OVP电压
|
||||||
{
|
{
|
||||||
get { return _OVP电压; }
|
get => _OVP电压;
|
||||||
set { SetProperty(ref _OVP电压, value); }
|
set => SetProperty(ref _OVP电压, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LineSeries _电压_lineSeries = new LineSeries { Title = "电压(V)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 电压_lineSeries
|
||||||
|
{
|
||||||
|
get => _电压_lineSeries;
|
||||||
|
set => SetProperty(ref _电压_lineSeries, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineSeries _电流_lineSeries = new LineSeries { Title = "电流(A)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 电流_lineSeries
|
||||||
|
{
|
||||||
|
get => _电流_lineSeries;
|
||||||
|
set => SetProperty(ref _电流_lineSeries, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineSeries _功率_lineSeries = new LineSeries { Title = "功率(W)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 功率_lineSeries
|
||||||
|
{
|
||||||
|
get => _功率_lineSeries;
|
||||||
|
set => SetProperty(ref _功率_lineSeries, value);
|
||||||
|
}
|
||||||
|
private NumericalDisplayViewModel _电压MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 电压MV
|
||||||
|
{
|
||||||
|
get => _电压MV;
|
||||||
|
set => SetProperty(ref _电压MV, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NumericalDisplayViewModel _电流MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 电流MV
|
||||||
|
{
|
||||||
|
get => _电流MV;
|
||||||
|
set => SetProperty(ref _电流MV, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NumericalDisplayViewModel _功率MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 功率MV
|
||||||
|
{
|
||||||
|
get => _功率MV;
|
||||||
|
set => SetProperty(ref _功率MV, value);
|
||||||
|
}
|
||||||
|
private PlotModel _曲线Model = new PlotModel();
|
||||||
|
public PlotModel 曲线Model
|
||||||
|
{
|
||||||
|
get => _曲线Model;
|
||||||
|
set => SetProperty(ref _曲线Model, value);
|
||||||
|
}
|
||||||
|
public DateTimeAxis TimeAxis { get; private set; }
|
||||||
|
public LinearAxis ValueAxis { get; private set; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 命令
|
#region 命令
|
||||||
public ICommand ConnectCommand { get; private set; }
|
public ICommand ConnectCommand { get; private set; }
|
||||||
public ICommand DisconnectCommand { get; private set; }
|
public ICommand DisconnectCommand { get; private set; }
|
||||||
@ -76,6 +128,7 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
public ICommand ClearOVPAlarmCommand { get; private set; }
|
public ICommand ClearOVPAlarmCommand { get; private set; }
|
||||||
public ICommand SetOVPCommand { get; private set; }
|
public ICommand SetOVPCommand { get; private set; }
|
||||||
public ICommand CloseCommand { get; private set; }
|
public ICommand CloseCommand { get; private set; }
|
||||||
|
public ICommand ResetViewCommand { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
private IEventAggregator _eventAggregator { get; set; }
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
@ -104,8 +157,56 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
_devices = containerProvider.Resolve<Devices>();
|
_devices = containerProvider.Resolve<Devices>();
|
||||||
_globalVariables = containerProvider.Resolve<GlobalVariables>();
|
_globalVariables = containerProvider.Resolve<GlobalVariables>();
|
||||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
ResetViewCommand = new DelegateCommand(ResetView);
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Subscribe(UpdateCurve);
|
||||||
|
InitCurve();
|
||||||
|
}
|
||||||
|
private void ResetView()
|
||||||
|
{
|
||||||
|
曲线Model.ResetAllAxes();
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
|
private void InitCurve()
|
||||||
|
{
|
||||||
|
TimeAxis = new DateTimeAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Bottom,
|
||||||
|
StringFormat = "HH:mm:ss",
|
||||||
|
IntervalType = DateTimeIntervalType.Seconds,
|
||||||
|
};
|
||||||
|
ValueAxis = new LinearAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Left,
|
||||||
|
};
|
||||||
|
曲线Model.Axes.Add(TimeAxis);
|
||||||
|
曲线Model.Axes.Add(ValueAxis);
|
||||||
|
曲线Model.Series.Add(电压_lineSeries);
|
||||||
|
曲线Model.Series.Add(电流_lineSeries);
|
||||||
|
曲线Model.Series.Add(功率_lineSeries);
|
||||||
|
曲线Model.Legends.Add(new Legend()
|
||||||
|
{
|
||||||
|
LegendPosition = LegendPosition.TopRight,
|
||||||
|
LegendOrientation = LegendOrientation.Vertical,
|
||||||
|
LegendPlacement = LegendPlacement.Inside
|
||||||
|
});
|
||||||
|
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateCurve((string device, Dictionary<string, double> data) tuple)
|
||||||
|
{
|
||||||
|
var (device, data) = tuple;
|
||||||
|
if (device != "IT6724C") return;
|
||||||
|
电流MV.MonitorValue = data["实时电流"];
|
||||||
|
电压MV.MonitorValue = data["实时电压"];
|
||||||
|
功率MV.MonitorValue = data["实时功率"];
|
||||||
|
|
||||||
|
var now = DateTimeAxis.ToDouble(DateTime.Now);
|
||||||
|
电流_lineSeries.Points.Add(new DataPoint(now, data["实时电流"]));
|
||||||
|
电压_lineSeries.Points.Add(new DataPoint(now, data["实时电压"]));
|
||||||
|
功率_lineSeries.Points.Add(new DataPoint(now, data["实时功率"]));
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
#region 命令处理方法
|
#region 命令处理方法
|
||||||
private void OnClose()
|
private void OnClose()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
using BOB.Singleton;
|
using BOB.Singleton;
|
||||||
|
using BOB.ViewModels.UserControls;
|
||||||
|
using Common.PubEvent;
|
||||||
using DeviceCommand.Device;
|
using DeviceCommand.Device;
|
||||||
using Logger;
|
using Logger;
|
||||||
|
using OxyPlot;
|
||||||
|
using OxyPlot.Axes;
|
||||||
|
using OxyPlot.Legends;
|
||||||
|
using OxyPlot.Series;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -48,7 +54,54 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
get { return _OCP电流; }
|
get { return _OCP电流; }
|
||||||
set { SetProperty(ref _OCP电流, value); }
|
set { SetProperty(ref _OCP电流, value); }
|
||||||
}
|
}
|
||||||
|
private LineSeries _电压_lineSeries = new LineSeries { Title = "电压(V)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 电压_lineSeries
|
||||||
|
{
|
||||||
|
get => _电压_lineSeries;
|
||||||
|
set => SetProperty(ref _电压_lineSeries, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineSeries _电流_lineSeries = new LineSeries { Title = "电流(A)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 电流_lineSeries
|
||||||
|
{
|
||||||
|
get => _电流_lineSeries;
|
||||||
|
set => SetProperty(ref _电流_lineSeries, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineSeries _功率_lineSeries = new LineSeries { Title = "功率(W)", StrokeThickness = 2 };
|
||||||
|
public LineSeries 功率_lineSeries
|
||||||
|
{
|
||||||
|
get => _功率_lineSeries;
|
||||||
|
set => SetProperty(ref _功率_lineSeries, value);
|
||||||
|
}
|
||||||
|
private NumericalDisplayViewModel _电压MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 电压MV
|
||||||
|
{
|
||||||
|
get => _电压MV;
|
||||||
|
set => SetProperty(ref _电压MV, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NumericalDisplayViewModel _电流MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 电流MV
|
||||||
|
{
|
||||||
|
get => _电流MV;
|
||||||
|
set => SetProperty(ref _电流MV, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NumericalDisplayViewModel _功率MV = new NumericalDisplayViewModel();
|
||||||
|
public NumericalDisplayViewModel 功率MV
|
||||||
|
{
|
||||||
|
get => _功率MV;
|
||||||
|
set => SetProperty(ref _功率MV, value);
|
||||||
|
}
|
||||||
|
private PlotModel _曲线Model = new PlotModel();
|
||||||
|
public PlotModel 曲线Model
|
||||||
|
{
|
||||||
|
get => _曲线Model;
|
||||||
|
set => SetProperty(ref _曲线Model, value);
|
||||||
|
}
|
||||||
|
public DateTimeAxis TimeAxis { get; private set; }
|
||||||
|
public LinearAxis ValueAxis { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
#region 命令
|
#region 命令
|
||||||
@ -66,6 +119,7 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
public ICommand SetCCCurrentCommand { get; private set; }
|
public ICommand SetCCCurrentCommand { get; private set; }
|
||||||
public ICommand SetOCPCurrentCommand { get; private set; }
|
public ICommand SetOCPCurrentCommand { get; private set; }
|
||||||
public ICommand CloseCommand { get; private set; }
|
public ICommand CloseCommand { get; private set; }
|
||||||
|
public ICommand ResetViewCommand { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
private IEventAggregator _eventAggregator { get; set; }
|
private IEventAggregator _eventAggregator { get; set; }
|
||||||
@ -90,7 +144,55 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
SetCCCurrentCommand = new AsyncDelegateCommand(OnSetCCCurrent);
|
SetCCCurrentCommand = new AsyncDelegateCommand(OnSetCCCurrent);
|
||||||
SetOCPCurrentCommand = new AsyncDelegateCommand(OnSetOCPCurrent);
|
SetOCPCurrentCommand = new AsyncDelegateCommand(OnSetOCPCurrent);
|
||||||
CloseCommand = new DelegateCommand(OnClose);
|
CloseCommand = new DelegateCommand(OnClose);
|
||||||
|
ResetViewCommand = new DelegateCommand(ResetView);
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Subscribe(UpdateCurve);
|
||||||
|
InitCurve();
|
||||||
|
}
|
||||||
|
private void ResetView()
|
||||||
|
{
|
||||||
|
曲线Model.ResetAllAxes();
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
|
private void InitCurve()
|
||||||
|
{
|
||||||
|
TimeAxis = new DateTimeAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Bottom,
|
||||||
|
StringFormat = "HH:mm:ss",
|
||||||
|
IntervalType = DateTimeIntervalType.Seconds,
|
||||||
|
};
|
||||||
|
ValueAxis = new LinearAxis
|
||||||
|
{
|
||||||
|
Position = AxisPosition.Left,
|
||||||
|
};
|
||||||
|
曲线Model.Axes.Add(TimeAxis);
|
||||||
|
曲线Model.Axes.Add(ValueAxis);
|
||||||
|
曲线Model.Series.Add(电压_lineSeries);
|
||||||
|
曲线Model.Series.Add(电流_lineSeries);
|
||||||
|
曲线Model.Series.Add(功率_lineSeries);
|
||||||
|
曲线Model.Legends.Add(new Legend()
|
||||||
|
{
|
||||||
|
LegendPosition = LegendPosition.TopRight,
|
||||||
|
LegendOrientation = LegendOrientation.Vertical,
|
||||||
|
LegendPlacement = LegendPlacement.Inside
|
||||||
|
});
|
||||||
|
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCurve((string device, Dictionary<string, double> data) tuple)
|
||||||
|
{
|
||||||
|
var (device, data) = tuple;
|
||||||
|
if (device != "IT6724C") return;
|
||||||
|
电流MV.MonitorValue = data["实时电流"];
|
||||||
|
电压MV.MonitorValue = data["实时电压"];
|
||||||
|
功率MV.MonitorValue = data["实时功率"];
|
||||||
|
|
||||||
|
var now = DateTimeAxis.ToDouble(DateTime.Now);
|
||||||
|
电流_lineSeries.Points.Add(new DataPoint(now, data["实时电流"]));
|
||||||
|
电压_lineSeries.Points.Add(new DataPoint(now, data["实时电压"]));
|
||||||
|
功率_lineSeries.Points.Add(new DataPoint(now, data["实时功率"]));
|
||||||
|
曲线Model.InvalidatePlot(true);
|
||||||
}
|
}
|
||||||
#region Command Handlers
|
#region Command Handlers
|
||||||
private void OnClose()
|
private void OnClose()
|
||||||
|
|||||||
@ -44,6 +44,7 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
_devices.Init(SystemConfig.Instance.DeviceList);
|
_devices.Init(SystemConfig.Instance.DeviceList);
|
||||||
await _devices.ConnectAllDevicesAsync();
|
await _devices.ConnectAllDevicesAsync();
|
||||||
|
_devices.StartPollingCollectionAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -51,7 +52,7 @@ namespace BOB.ViewModels
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_eventAggregator.GetEvent<WaitingEvent>().Publish(false);
|
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#region 导航
|
#region 导航
|
||||||
@ -61,7 +62,7 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
if (!_isInitialized)
|
if (!_isInitialized)
|
||||||
{
|
{
|
||||||
_eventAggregator.GetEvent<WaitingEvent>().Publish(true);
|
_eventAggregator.GetEvent<OverlayEvent>().Publish(true);
|
||||||
_ = InitializeDevicesAsync();
|
_ = InitializeDevicesAsync();
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
using BOB.Singleton;
|
using BOB.Services;
|
||||||
|
using BOB.Singleton;
|
||||||
|
using Common.PubEvent;
|
||||||
using Common.PubEvents;
|
using Common.PubEvents;
|
||||||
using Logger;
|
using Logger;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using OxyPlot;
|
using OxyPlot;
|
||||||
|
using OxyPlot.Axes;
|
||||||
using OxyPlot.Legends;
|
using OxyPlot.Legends;
|
||||||
using OxyPlot.Series;
|
using OxyPlot.Series;
|
||||||
using Prism.Dialogs;
|
using Prism.Dialogs;
|
||||||
@ -10,6 +13,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
@ -27,13 +31,6 @@ namespace BOB.ViewModels
|
|||||||
get => _CurveModel;
|
get => _CurveModel;
|
||||||
set => SetProperty(ref _CurveModel, value);
|
set => SetProperty(ref _CurveModel, value);
|
||||||
}
|
}
|
||||||
private List<LineSeries> _signalSeries = new List<LineSeries>();
|
|
||||||
|
|
||||||
public List<LineSeries> SignalSeries
|
|
||||||
{
|
|
||||||
get => _signalSeries;
|
|
||||||
set => SetProperty(ref _signalSeries, value);
|
|
||||||
}
|
|
||||||
private Dictionary<string, LineSeries> _SeriesDic = new ();
|
private Dictionary<string, LineSeries> _SeriesDic = new ();
|
||||||
|
|
||||||
public Dictionary<string,LineSeries> SeriesDic
|
public Dictionary<string,LineSeries> SeriesDic
|
||||||
@ -69,12 +66,19 @@ namespace BOB.ViewModels
|
|||||||
get => _SelectedSaveDays;
|
get => _SelectedSaveDays;
|
||||||
set => SetProperty(ref _SelectedSaveDays, value);
|
set => SetProperty(ref _SelectedSaveDays, value);
|
||||||
}
|
}
|
||||||
private ObservableCollection<string> _CurSingleList=new();
|
//private ObservableCollection<string> _CurSingleList=new();
|
||||||
|
|
||||||
public ObservableCollection<string> CurSingleList
|
public ObservableCollection<string> CurSingleList
|
||||||
{
|
{
|
||||||
get => _CurSingleList;
|
get => SystemConfig.Instance.CurSingleList;
|
||||||
set => SetProperty(ref _CurSingleList, value);
|
set
|
||||||
|
{
|
||||||
|
if (SystemConfig.Instance.CurSingleList != value)
|
||||||
|
{
|
||||||
|
SystemConfig.Instance.CurSingleList = value;
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private ObservableCollection<string> _DeviceSingleList = new();
|
private ObservableCollection<string> _DeviceSingleList = new();
|
||||||
|
|
||||||
@ -83,8 +87,6 @@ namespace BOB.ViewModels
|
|||||||
get => _DeviceSingleList;
|
get => _DeviceSingleList;
|
||||||
set => SetProperty(ref _DeviceSingleList, value);
|
set => SetProperty(ref _DeviceSingleList, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
#region 命令
|
#region 命令
|
||||||
public ICommand ResetViewCommand { get; set; }
|
public ICommand ResetViewCommand { get; set; }
|
||||||
@ -97,135 +99,113 @@ namespace BOB.ViewModels
|
|||||||
private IEventAggregator _eventAggregator;
|
private IEventAggregator _eventAggregator;
|
||||||
private IDialogService _dialogService;
|
private IDialogService _dialogService;
|
||||||
private static Random _random = new Random();
|
private static Random _random = new Random();
|
||||||
|
private DispatcherTimer _refreshTimer;
|
||||||
private Devices _devices { get; set; }
|
private Devices _devices { get; set; }
|
||||||
|
private readonly IProgress<(string name, double value)> _progress;
|
||||||
public MonitorViewModel(IEventAggregator eventAggregator, IDialogService dialogService, IContainerProvider containerProvider )
|
public MonitorViewModel(IEventAggregator eventAggregator, IDialogService dialogService, IContainerProvider containerProvider )
|
||||||
{
|
{
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
_devices = containerProvider.Resolve<Devices>();
|
_devices = containerProvider.Resolve<Devices>();
|
||||||
ResetViewCommand = new DelegateCommand(ResetView);
|
ResetViewCommand = new DelegateCommand(ResetView);
|
||||||
AddSignalCommand = new DelegateCommand(AddSignal);
|
AddSignalCommand = new DelegateCommand<string>(AddSignal);
|
||||||
RemoveSignalCommand = new DelegateCommand(RemoveSignal);
|
RemoveSignalCommand = new DelegateCommand(RemoveSignal);
|
||||||
ChanegPathCommand = new DelegateCommand(ChanegPath);
|
ChanegPathCommand = new DelegateCommand(ChanegPath);
|
||||||
SaveCommand = new DelegateCommand(Save);
|
SaveCommand = new DelegateCommand(Save);
|
||||||
|
_eventAggregator.GetEvent<CurveDataEvent>().Subscribe(OnCurveDataReceived);
|
||||||
|
_progress = new Progress<(string name, double value)>(UpdateCurveOnUI);
|
||||||
InitData();
|
InitData();
|
||||||
|
|
||||||
// 初始化模拟量曲线
|
|
||||||
InitializeSimulatedSignals();
|
|
||||||
|
|
||||||
// 设置定时器定时更新模拟数据
|
|
||||||
_timer = new DispatcherTimer
|
|
||||||
{
|
|
||||||
Interval = TimeSpan.FromSeconds(0.5) // 每1秒更新一次
|
|
||||||
};
|
|
||||||
_timer.Tick += (s, e) => UpdateSimulatedData();
|
|
||||||
_timer.Start();
|
|
||||||
}
|
}
|
||||||
|
private void UpdateCurveOnUI((string name, double value) update)
|
||||||
|
{
|
||||||
|
var (signalName, value) = update;
|
||||||
|
|
||||||
|
if (!SeriesDic.TryGetValue(signalName, out var line))
|
||||||
|
return;
|
||||||
|
|
||||||
|
line.Points.Add(DateTimeAxis.CreateDataPoint(DateTime.Now, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnCurveDataReceived((string device, Dictionary<string, double> data) tuple)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
var (device, data) = tuple;
|
||||||
|
foreach (var item in data)
|
||||||
|
{
|
||||||
|
string propname = item.Key;
|
||||||
|
double value = item.Value;
|
||||||
|
string signalName = device + "." + propname;
|
||||||
|
|
||||||
|
if (CurSingleList.Contains(signalName))
|
||||||
|
{
|
||||||
|
// 通过 Progress 安全更新 UI
|
||||||
|
_progress.Report((signalName, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void InitData()
|
private void InitData()
|
||||||
{
|
{
|
||||||
SelectedSaveDays=SystemConfig.Instance.SaveDay.ToString();
|
SelectedSaveDays=SystemConfig.Instance.SaveDay.ToString();
|
||||||
FilePath= SystemConfig.Instance.DBSavePath;
|
FilePath= SystemConfig.Instance.DBSavePath;
|
||||||
}
|
foreach (var _PollingRead in _devices.PollingReadDic)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region 模拟量
|
|
||||||
|
|
||||||
private DispatcherTimer _timer;
|
|
||||||
private double _time = 0;
|
|
||||||
|
|
||||||
private void InitializeSimulatedSignals()
|
|
||||||
{
|
|
||||||
CurveModel.Legends.Add(new Legend
|
|
||||||
{
|
{
|
||||||
LegendPosition= LegendPosition.TopLeft,
|
string deviceName = _PollingRead.Key;
|
||||||
IsLegendVisible=true
|
PollingRead pollingRead = _PollingRead.Value;
|
||||||
});
|
|
||||||
// 模拟四个信号的初始化
|
|
||||||
|
|
||||||
// 模拟量1:正弦波
|
var props = pollingRead.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||||
var sineSignal = new LineSeries
|
.Where(p => p.PropertyType == typeof(double));
|
||||||
{
|
|
||||||
Title = "正弦波信号",
|
|
||||||
MarkerType = MarkerType.Circle,
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Color = OxyColors.Red
|
|
||||||
};
|
|
||||||
_signalSeries.Add(sineSignal);
|
|
||||||
SeriesDic.Add(sineSignal.Title, sineSignal);
|
|
||||||
|
|
||||||
// 模拟量2:线性增长
|
foreach (var prop in props)
|
||||||
var linearSignal = new LineSeries
|
{
|
||||||
{
|
DeviceSingleList.Add(deviceName + "." + prop.Name);
|
||||||
Title = "线性增长信号",
|
}
|
||||||
MarkerType = MarkerType.Square,
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Color = OxyColors.Green
|
|
||||||
};
|
|
||||||
_signalSeries.Add(linearSignal);
|
|
||||||
SeriesDic.Add(linearSignal.Title, linearSignal);
|
|
||||||
|
|
||||||
// 模拟量3:随机波动
|
|
||||||
var randomSignal = new LineSeries
|
|
||||||
{
|
|
||||||
Title = "随机波动信号",
|
|
||||||
MarkerType = MarkerType.Triangle,
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Color = OxyColors.Blue
|
|
||||||
};
|
|
||||||
_signalSeries.Add(randomSignal);
|
|
||||||
SeriesDic.Add(randomSignal.Title, randomSignal);
|
|
||||||
|
|
||||||
// 模拟量4:指数衰减
|
|
||||||
var exponentialSignal = new LineSeries
|
|
||||||
{
|
|
||||||
Title = "指数衰减信号",
|
|
||||||
MarkerType = MarkerType.Diamond,
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Color = OxyColors.Orange
|
|
||||||
};
|
|
||||||
_signalSeries.Add(exponentialSignal);
|
|
||||||
SeriesDic.Add(exponentialSignal.Title, exponentialSignal);
|
|
||||||
|
|
||||||
// 将模拟量曲线添加到图表中
|
|
||||||
foreach (var signal in _signalSeries)
|
|
||||||
{
|
|
||||||
CurveModel.Series.Add(signal);
|
|
||||||
}
|
}
|
||||||
|
foreach(var curve in CurSingleList)
|
||||||
|
{
|
||||||
|
AddSignal(curve);
|
||||||
|
}
|
||||||
|
InitCurveModel();
|
||||||
|
InitTimer();
|
||||||
}
|
}
|
||||||
private void UpdateSimulatedData()
|
private void InitCurveModel()
|
||||||
{
|
{
|
||||||
// 更新模拟量的值并添加新的数据点
|
CurveModel.Axes.Clear();
|
||||||
|
|
||||||
// 模拟量1:正弦波
|
var timeAxis = new DateTimeAxis
|
||||||
var sineSignal = _signalSeries[0];
|
{
|
||||||
sineSignal.Points.Add(new DataPoint(_time, Math.Sin(_time)));
|
Position = AxisPosition.Bottom,
|
||||||
if (sineSignal.Points.Count > 1000) sineSignal.Points.RemoveAt(0); // 保持最多100个点
|
StringFormat = "HH:mm:ss",
|
||||||
|
Title = "时间",
|
||||||
|
IntervalType = DateTimeIntervalType.Seconds
|
||||||
|
};
|
||||||
|
CurveModel.Axes.Add(timeAxis);
|
||||||
|
|
||||||
// 模拟量2:线性增长
|
var valueAxis = new LinearAxis
|
||||||
var linearSignal = _signalSeries[1];
|
{
|
||||||
linearSignal.Points.Add(new DataPoint(_time, _time));
|
Position = AxisPosition.Left,
|
||||||
if (linearSignal.Points.Count > 1000) linearSignal.Points.RemoveAt(0); // 保持最多100个点
|
Title = "数值"
|
||||||
|
};
|
||||||
// 模拟量3:随机波动
|
CurveModel.Axes.Add(valueAxis);
|
||||||
var randomSignal = _signalSeries[2];
|
|
||||||
var randomValue = 10 * (2 * new Random().NextDouble() - 1); // 随机波动范围 [-10, 10]
|
|
||||||
randomSignal.Points.Add(new DataPoint(_time, randomValue));
|
|
||||||
if (randomSignal.Points.Count > 1000) randomSignal.Points.RemoveAt(0); // 保持最多100个点
|
|
||||||
|
|
||||||
// 模拟量4:指数衰减
|
|
||||||
var exponentialSignal = _signalSeries[3];
|
|
||||||
exponentialSignal.Points.Add(new DataPoint(_time, Math.Exp(-0.1 * _time)));
|
|
||||||
if (exponentialSignal.Points.Count > 1000) exponentialSignal.Points.RemoveAt(0); // 保持最多100个点
|
|
||||||
|
|
||||||
// 更新图表
|
|
||||||
CurveModel.InvalidatePlot(true);
|
|
||||||
|
|
||||||
// 时间前进
|
|
||||||
_time += 0.5; // 每次增加0.1秒
|
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
private void InitTimer()
|
||||||
|
{
|
||||||
|
_refreshTimer = new DispatcherTimer
|
||||||
|
{
|
||||||
|
Interval = TimeSpan.FromSeconds(1)
|
||||||
|
};
|
||||||
|
_refreshTimer.Tick += (s, e) =>
|
||||||
|
{
|
||||||
|
CurveModel.InvalidatePlot(true);
|
||||||
|
};
|
||||||
|
_refreshTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private OxyColor GetRandomColor()
|
private OxyColor GetRandomColor()
|
||||||
{
|
{
|
||||||
// 生成随机的红色、绿色、蓝色分量,范围是 0 到 255
|
// 生成随机的红色、绿色、蓝色分量,范围是 0 到 255
|
||||||
@ -237,28 +217,62 @@ namespace BOB.ViewModels
|
|||||||
return OxyColor.FromRgb(r, g, b);
|
return OxyColor.FromRgb(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddSignal()
|
private void AddSignal(string Curve="")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_SeriesDic.ContainsKey(SelectCurve))
|
if (Curve == null)
|
||||||
{
|
{
|
||||||
return;
|
if (_SeriesDic.ContainsKey(SelectCurve))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var sineSignal = new LineSeries
|
||||||
|
{
|
||||||
|
Title = SelectCurve,
|
||||||
|
MarkerType = MarkerType.Circle,
|
||||||
|
StrokeThickness = 2,
|
||||||
|
Color = GetRandomColor()
|
||||||
|
};
|
||||||
|
CurveModel.Series.Add(sineSignal);
|
||||||
|
CurveModel.Legends.Add(new Legend
|
||||||
|
{
|
||||||
|
LegendPosition = LegendPosition.TopCenter, // 图表顶部中间
|
||||||
|
LegendOrientation = LegendOrientation.Horizontal, // 横向排列
|
||||||
|
LegendPlacement = LegendPlacement.Inside, // 放在图上面
|
||||||
|
LegendBorderThickness = 0, // 去掉边框,可选
|
||||||
|
LegendBackground = OxyColors.WhiteSmoke // 背景色,可选
|
||||||
|
});
|
||||||
|
|
||||||
|
SeriesDic.Add(SelectCurve, sineSignal);
|
||||||
|
CurSingleList.Add(SelectCurve);
|
||||||
|
SystemConfig.Instance.SaveToFile();
|
||||||
|
CurveModel.InvalidatePlot(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 开启资源
|
|
||||||
|
|
||||||
var sineSignal = new LineSeries
|
var sineSignal = new LineSeries
|
||||||
{
|
{
|
||||||
Title = SelectCurve,
|
Title = Curve,
|
||||||
MarkerType = MarkerType.Circle,
|
MarkerType = MarkerType.Circle,
|
||||||
StrokeThickness = 2,
|
StrokeThickness = 2,
|
||||||
Color = GetRandomColor()
|
Color = GetRandomColor()
|
||||||
};
|
};
|
||||||
CurveModel.Series.Add(sineSignal);
|
CurveModel.Series.Add(sineSignal);
|
||||||
SeriesDic.Add(SelectCurve, sineSignal);
|
CurveModel.Legends.Add(new Legend
|
||||||
CurSingleList.Add(SelectCurve);
|
{
|
||||||
|
LegendPosition = LegendPosition.TopCenter, // 图表顶部中间
|
||||||
|
LegendOrientation = LegendOrientation.Horizontal, // 横向排列
|
||||||
|
LegendPlacement = LegendPlacement.Inside, // 放在图上面
|
||||||
|
LegendBorderThickness = 0, // 去掉边框,可选
|
||||||
|
LegendBackground = OxyColors.WhiteSmoke // 背景色,可选
|
||||||
|
});
|
||||||
|
|
||||||
|
SeriesDic.Add(Curve, sineSignal);
|
||||||
CurveModel.InvalidatePlot(true);
|
CurveModel.InvalidatePlot(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,9 +291,8 @@ namespace BOB.ViewModels
|
|||||||
_SeriesDic.Remove(SelectDeleteCurve);
|
_SeriesDic.Remove(SelectDeleteCurve);
|
||||||
CurveModel.Series.Remove(signalToRemove);
|
CurveModel.Series.Remove(signalToRemove);
|
||||||
CurSingleList.Remove(SelectDeleteCurve);
|
CurSingleList.Remove(SelectDeleteCurve);
|
||||||
|
SystemConfig.Instance.SaveToFile();
|
||||||
CurveModel.InvalidatePlot(true);
|
CurveModel.InvalidatePlot(true);
|
||||||
|
|
||||||
// 释放资源
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -336,7 +349,7 @@ namespace BOB.ViewModels
|
|||||||
#region 导航
|
#region 导航
|
||||||
public void OnNavigatedTo(NavigationContext navigationContext)
|
public void OnNavigatedTo(NavigationContext navigationContext)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsNavigationTarget(NavigationContext navigationContext)
|
public bool IsNavigationTarget(NavigationContext navigationContext)
|
||||||
|
|||||||
@ -176,6 +176,7 @@ namespace BOB.ViewModels
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_eventAggregator.GetEvent<ConnectionChangeEvent>().Publish((DeviceList[i].Remark, isConnected));
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.Report((i, isConnected));
|
progress.Report((i, isConnected));
|
||||||
|
|||||||
@ -145,7 +145,7 @@ namespace BOB.ViewModels
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "更新信息":
|
case "更新信息":
|
||||||
|
_regionManager.RequestNavigate("ShellViewManager", "UpdateInfoView");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
46
BOB/ViewModels/UpdateInfoViewModel.cs
Normal file
46
BOB/ViewModels/UpdateInfoViewModel.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using Model;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using Prism.Ioc;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace BOB.ViewModels
|
||||||
|
{
|
||||||
|
public class UpdateInfoViewModel : BindableBase
|
||||||
|
{
|
||||||
|
private List<UpdateInfoModel> _updateList;
|
||||||
|
public List<UpdateInfoModel> UpdateList
|
||||||
|
{
|
||||||
|
get => _updateList;
|
||||||
|
set => SetProperty(ref _updateList, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UpdateInfoViewModel(IContainerProvider containerProvider)
|
||||||
|
{
|
||||||
|
string path = Path.Combine(SystemConfig.Instance.SystemPath, "UpdateInfo.json");
|
||||||
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(path, Encoding.UTF8);
|
||||||
|
UpdateList = JsonConvert.DeserializeObject<List<UpdateInfoModel>>(json)
|
||||||
|
?? new List<UpdateInfoModel>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
UpdateList = new List<UpdateInfoModel>();
|
||||||
|
Console.WriteLine("读取 UpdateInfo.json 出错: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
UpdateList = new List<UpdateInfoModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@
|
|||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:ucs="clr-namespace:BOB.Views.UserControls"
|
||||||
Background="White"
|
Background="White"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
Height="850"
|
Height="850"
|
||||||
@ -27,7 +28,6 @@
|
|||||||
<!-- 实时监控 -->
|
<!-- 实时监控 -->
|
||||||
<GroupBox x:Name="实时监控区"
|
<GroupBox x:Name="实时监控区"
|
||||||
Header="实时监控"
|
Header="实时监控"
|
||||||
Grid.Column="1"
|
|
||||||
Padding="0,0,0,0">
|
Padding="0,0,0,0">
|
||||||
<Grid Grid.Row="0">
|
<Grid Grid.Row="0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@ -35,7 +35,12 @@
|
|||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 电压MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="0" />
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 电流MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="1" />
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 功率MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="2" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
@ -43,7 +48,14 @@
|
|||||||
<GroupBox Header="实时曲线"
|
<GroupBox Header="实时曲线"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Padding="0,0,0,0">
|
Padding="0,0,0,0">
|
||||||
<oxy:PlotView Model="{Binding 曲线Model}" />
|
<oxy:PlotView Model="{Binding 曲线Model}">
|
||||||
|
<oxy:PlotView.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="视图复位"
|
||||||
|
Command="{Binding ResetViewCommand}" />
|
||||||
|
</ContextMenu>
|
||||||
|
</oxy:PlotView.ContextMenu>
|
||||||
|
</oxy:PlotView>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<!-- 调试选项 -->
|
<!-- 调试选项 -->
|
||||||
|
|||||||
@ -50,7 +50,14 @@
|
|||||||
<GroupBox Header="实时曲线"
|
<GroupBox Header="实时曲线"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Padding="0,0,0,0">
|
Padding="0,0,0,0">
|
||||||
<oxy:PlotView Model="{Binding 曲线Model}" />
|
<oxy:PlotView Model="{Binding 曲线Model}">
|
||||||
|
<oxy:PlotView.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="视图复位"
|
||||||
|
Command="{Binding ResetViewCommand}" />
|
||||||
|
</ContextMenu>
|
||||||
|
</oxy:PlotView.ContextMenu>
|
||||||
|
</oxy:PlotView>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<!-- 调试选项 -->
|
<!-- 调试选项 -->
|
||||||
|
|||||||
@ -15,8 +15,10 @@
|
|||||||
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
||||||
TargetType="Window" />
|
TargetType="Window" />
|
||||||
</prism:Dialog.WindowStyle>
|
</prism:Dialog.WindowStyle>
|
||||||
<Grid MouseLeftButtonDown="MouseLeftButtonDown">
|
<GroupBox Header="IO板卡手动设置"
|
||||||
<TreeView Margin="10">
|
Padding="0,0,0,0">
|
||||||
|
<Grid MouseLeftButtonDown="MouseLeftButtonDown">
|
||||||
|
<TreeView Margin="10">
|
||||||
<TreeViewItem Header="连接状态设置">
|
<TreeViewItem Header="连接状态设置">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Content="连接"
|
<Button Content="连接"
|
||||||
@ -74,13 +76,14 @@
|
|||||||
</TreeViewItem>
|
</TreeViewItem>
|
||||||
</TreeViewItem>
|
</TreeViewItem>
|
||||||
</TreeView>
|
</TreeView>
|
||||||
<StackPanel Grid.Row="2"
|
<StackPanel Grid.Row="2"
|
||||||
VerticalAlignment="Bottom">
|
VerticalAlignment="Bottom">
|
||||||
<Button Content="关闭"
|
<Button Content="关闭"
|
||||||
Width="70"
|
Width="70"
|
||||||
Margin="10"
|
Margin="10"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Command="{Binding CloseCommand}" />
|
Command="{Binding CloseCommand}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:BOB.Views.Dialogs"
|
xmlns:local="clr-namespace:BOB.Views.Dialogs"
|
||||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
|
xmlns:ucs="clr-namespace:BOB.Views.UserControls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
@ -26,15 +27,34 @@
|
|||||||
|
|
||||||
<GroupBox x:Name="实时监控区"
|
<GroupBox x:Name="实时监控区"
|
||||||
Header="实时监控"
|
Header="实时监控"
|
||||||
Grid.Row="0"
|
|
||||||
Padding="0,0,0,0">
|
Padding="0,0,0,0">
|
||||||
|
<Grid Grid.Row="0">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 电压MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="0" />
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 电流MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="1" />
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 功率MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="2" />
|
||||||
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
|
<!-- 实时曲线 -->
|
||||||
<GroupBox Header="实时曲线"
|
<GroupBox Header="实时曲线"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Padding="0,0,0,0">
|
Padding="0,0,0,0">
|
||||||
<oxy:PlotView Model="{Binding 曲线Model}" />
|
<oxy:PlotView Model="{Binding 曲线Model}">
|
||||||
|
<oxy:PlotView.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="视图复位"
|
||||||
|
Command="{Binding ResetViewCommand}" />
|
||||||
|
</ContextMenu>
|
||||||
|
</oxy:PlotView.ContextMenu>
|
||||||
|
</oxy:PlotView>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="调试选项"
|
<GroupBox Header="调试选项"
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:BOB.Views.Dialogs"
|
xmlns:local="clr-namespace:BOB.Views.Dialogs"
|
||||||
xmlns:oxy="http://oxyplot.org/wpf"
|
xmlns:oxy="http://oxyplot.org/wpf"
|
||||||
|
xmlns:ucs="clr-namespace:BOB.Views.UserControls"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
@ -26,15 +27,33 @@
|
|||||||
|
|
||||||
<GroupBox x:Name="实时监控区"
|
<GroupBox x:Name="实时监控区"
|
||||||
Header="实时监控"
|
Header="实时监控"
|
||||||
Grid.Column="1"
|
|
||||||
Padding="0,0,0,0">
|
Padding="0,0,0,0">
|
||||||
|
<Grid Grid.Row="0">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 电压MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="0" />
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 电流MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="1" />
|
||||||
|
<ucs:NumericalDisplay DataContext="{Binding 功率MV,Mode=TwoWay}"
|
||||||
|
Grid.Column="2" />
|
||||||
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="实时曲线"
|
<GroupBox Header="实时曲线"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Padding="0,0,0,0">
|
Padding="0,0,0,0">
|
||||||
<oxy:PlotView Model="{Binding 曲线Model}" />
|
<oxy:PlotView Model="{Binding 曲线Model}">
|
||||||
|
<oxy:PlotView.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="视图复位"
|
||||||
|
Command="{Binding ResetViewCommand}" />
|
||||||
|
</ContextMenu>
|
||||||
|
</oxy:PlotView.ContextMenu>
|
||||||
|
</oxy:PlotView>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="调试选项"
|
<GroupBox Header="调试选项"
|
||||||
|
|||||||
@ -16,52 +16,102 @@
|
|||||||
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
||||||
TargetType="Window" />
|
TargetType="Window" />
|
||||||
</prism:Dialog.WindowStyle>
|
</prism:Dialog.WindowStyle>
|
||||||
<Grid MouseLeftButtonDown="MouseLeftButtonDown">
|
<GroupBox Header="AC源手动设置"
|
||||||
<TreeView Margin="10">
|
Padding="0,0,0,0">
|
||||||
<TreeViewItem Header="连接状态设置">
|
<Grid MouseLeftButtonDown="MouseLeftButtonDown">
|
||||||
<StackPanel Orientation="Horizontal">
|
<TreeView Margin="10">
|
||||||
<Button Content="连接"
|
<TreeViewItem Header="连接状态设置">
|
||||||
Margin="5"
|
<StackPanel Orientation="Horizontal">
|
||||||
Command="{Binding ConnectCommand}" />
|
<Button Content="连接"
|
||||||
<Button Content="断开"
|
Margin="5"
|
||||||
Margin="5"
|
Command="{Binding ConnectCommand}" />
|
||||||
Command="{Binding DisconnectCommand}" />
|
<Button Content="断开"
|
||||||
</StackPanel>
|
Margin="5"
|
||||||
</TreeViewItem>
|
Command="{Binding DisconnectCommand}" />
|
||||||
<TreeViewItem Header="电压开关设置">
|
</StackPanel>
|
||||||
<StackPanel Orientation="Horizontal">
|
</TreeViewItem>
|
||||||
<Button Content="开启"
|
<TreeViewItem Header="电压开关设置">
|
||||||
Margin="5"
|
<StackPanel Orientation="Horizontal">
|
||||||
Command="{Binding OpenPowerSupplyCommand}" />
|
<Button Content="开启"
|
||||||
<Button Content="关闭"
|
Margin="5"
|
||||||
Margin="5"
|
Command="{Binding OpenPowerSupplyCommand}" />
|
||||||
Command="{Binding ClosePowerSupplyCommand}" />
|
<Button Content="关闭"
|
||||||
</StackPanel>
|
Margin="5"
|
||||||
</TreeViewItem>
|
Command="{Binding ClosePowerSupplyCommand}" />
|
||||||
|
</StackPanel>
|
||||||
|
</TreeViewItem>
|
||||||
|
|
||||||
<TreeViewItem Header="设置">
|
<TreeViewItem Header="设置">
|
||||||
<TreeViewItem Header="设定三相电压输出">
|
<TreeViewItem Header="设定三相电压输出">
|
||||||
<TreeViewItem Header="设定三相电压档位">
|
<TreeViewItem Header="设定三相电压档位">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Content="低档"
|
<Button Content="低档"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{Binding SetVoltageLevelLowCommand}" />
|
Command="{Binding SetVoltageLevelLowCommand}" />
|
||||||
<Button Content="高档"
|
<Button Content="高档"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{Binding SetVoltageLevelHighCommand}" />
|
Command="{Binding SetVoltageLevelHighCommand}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</TreeViewItem>
|
||||||
|
|
||||||
|
<TreeViewItem Header="输出">
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<Button Content="设定三相输出电压"
|
||||||
|
Margin="5"
|
||||||
|
Command="{Binding SetThreePhaseVoltageCommand}" />
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Label Content="U相输出电压"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<TextBox Text="{Binding UPhaseVoltage}"
|
||||||
|
MinWidth="50"
|
||||||
|
materialDesign:HintAssist.Hint=""
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<Label Content="V"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Label Content="V相输出电压"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<TextBox Text="{Binding VPhaseVoltage}"
|
||||||
|
MinWidth="50"
|
||||||
|
materialDesign:HintAssist.Hint=""
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<Label Content="V"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Label Content="W相输出电压"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<TextBox Text="{Binding WPhaseVoltage}"
|
||||||
|
MinWidth="50"
|
||||||
|
materialDesign:HintAssist.Hint=""
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<Label Content="V"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</TreeViewItem>
|
||||||
</TreeViewItem>
|
</TreeViewItem>
|
||||||
|
|
||||||
<TreeViewItem Header="输出">
|
<TreeViewItem Header="设定通用功能输出">
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<Button Content="设定三相输出电压"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding SetThreePhaseVoltageCommand}" />
|
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Label Content="U相输出电压"
|
<Button Content="设定通用功能输出电压"
|
||||||
|
Margin="5"
|
||||||
|
Command="{Binding SetCommonOutputVoltageCommand}" />
|
||||||
|
<Label Content="输出电压"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
<TextBox Text="{Binding UPhaseVoltage}"
|
<TextBox Text="{Binding CommonOutputVoltage}"
|
||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
materialDesign:HintAssist.Hint=""
|
materialDesign:HintAssist.Hint=""
|
||||||
Margin="5"
|
Margin="5"
|
||||||
@ -71,134 +121,87 @@
|
|||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Label Content="V相输出电压"
|
<Button Content="设定通用功能输出频率"
|
||||||
|
Margin="5"
|
||||||
|
Command="{Binding SetCommonOutputFrequencyCommand}" />
|
||||||
|
<Label Content="输出频率"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
<TextBox Text="{Binding VPhaseVoltage}"
|
<TextBox Text="{Binding CommonOutputFrequency}"
|
||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
materialDesign:HintAssist.Hint=""
|
|
||||||
Margin="5"
|
Margin="5"
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<Label Content="V"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
</StackPanel>
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<Label Content="W相输出电压"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<TextBox Text="{Binding WPhaseVoltage}"
|
|
||||||
MinWidth="50"
|
|
||||||
materialDesign:HintAssist.Hint=""
|
materialDesign:HintAssist.Hint=""
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
<Label Content="V"
|
<Label Content="Hz"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</TreeViewItem>
|
</TreeViewItem>
|
||||||
</TreeViewItem>
|
|
||||||
|
|
||||||
<TreeViewItem Header="设定通用功能输出">
|
<TreeViewItem Header="设定步阶功能输出">
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Content="设定通用功能输出电压"
|
<Button Content="设定步阶功能输出电压"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{Binding SetCommonOutputVoltageCommand}" />
|
Command="{Binding SetStepOutputVoltageCommand}" />
|
||||||
<Label Content="输出电压"
|
<Label Content="组号"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
<TextBox Text="{Binding CommonOutputVoltage}"
|
<TextBox Text="{Binding StepOutputVoltageGroup}"
|
||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
materialDesign:HintAssist.Hint=""
|
Margin="5"
|
||||||
Margin="5"
|
materialDesign:HintAssist.Hint=""
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
<Label Content="V"
|
<Label Content="输出电压"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
|
<TextBox Text="{Binding StepOutputVoltage}"
|
||||||
|
MinWidth="50"
|
||||||
|
Margin="5"
|
||||||
|
materialDesign:HintAssist.Hint=""
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<Label Content="V"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Button Content="设定步阶功能输出频率"
|
||||||
|
Margin="5"
|
||||||
|
Command="{Binding SetStepOutputFrequencyCommand}" />
|
||||||
|
<Label Content="组号"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<TextBox Text="{Binding StepOutputFrequencyGroup}"
|
||||||
|
MinWidth="50"
|
||||||
|
Margin="5"
|
||||||
|
materialDesign:HintAssist.Hint=""
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<Label Content="输出频率"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<TextBox Text="{Binding StepOutputFrequency}"
|
||||||
|
MinWidth="50"
|
||||||
|
Margin="5"
|
||||||
|
materialDesign:HintAssist.Hint=""
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
<Label Content="Hz"
|
||||||
|
Margin="5"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Orientation="Horizontal">
|
</TreeViewItem>
|
||||||
<Button Content="设定通用功能输出频率"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding SetCommonOutputFrequencyCommand}" />
|
|
||||||
<Label Content="输出频率"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<TextBox Text="{Binding CommonOutputFrequency}"
|
|
||||||
MinWidth="50"
|
|
||||||
Margin="5"
|
|
||||||
materialDesign:HintAssist.Hint=""
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<Label Content="Hz"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
</StackPanel>
|
|
||||||
</StackPanel>
|
|
||||||
</TreeViewItem>
|
|
||||||
|
|
||||||
<TreeViewItem Header="设定步阶功能输出">
|
|
||||||
<StackPanel Orientation="Vertical">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<Button Content="设定步阶功能输出电压"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding SetStepOutputVoltageCommand}" />
|
|
||||||
<Label Content="组号"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<TextBox Text="{Binding StepOutputVoltageGroup}"
|
|
||||||
MinWidth="50"
|
|
||||||
Margin="5"
|
|
||||||
materialDesign:HintAssist.Hint=""
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<Label Content="输出电压"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<TextBox Text="{Binding StepOutputVoltage}"
|
|
||||||
MinWidth="50"
|
|
||||||
Margin="5"
|
|
||||||
materialDesign:HintAssist.Hint=""
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<Label Content="V"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
</StackPanel>
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<Button Content="设定步阶功能输出频率"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding SetStepOutputFrequencyCommand}" />
|
|
||||||
<Label Content="组号"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<TextBox Text="{Binding StepOutputFrequencyGroup}"
|
|
||||||
MinWidth="50"
|
|
||||||
Margin="5"
|
|
||||||
materialDesign:HintAssist.Hint=""
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<Label Content="输出频率"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<TextBox Text="{Binding StepOutputFrequency}"
|
|
||||||
MinWidth="50"
|
|
||||||
Margin="5"
|
|
||||||
materialDesign:HintAssist.Hint=""
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
<Label Content="Hz"
|
|
||||||
Margin="5"
|
|
||||||
VerticalContentAlignment="Center" />
|
|
||||||
</StackPanel>
|
|
||||||
</StackPanel>
|
|
||||||
</TreeViewItem>
|
</TreeViewItem>
|
||||||
|
</TreeView>
|
||||||
</TreeViewItem>
|
<StackPanel Grid.Row="2"
|
||||||
</TreeView>
|
VerticalAlignment="Bottom">
|
||||||
<StackPanel Grid.Row="2"
|
<Button Content="关闭"
|
||||||
VerticalAlignment="Bottom">
|
Width="70"
|
||||||
<Button Content="关闭"
|
Margin="10"
|
||||||
Width="70"
|
HorizontalAlignment="Right"
|
||||||
Margin="10"
|
Command="{Binding CloseCommand}" />
|
||||||
HorizontalAlignment="Right"
|
</StackPanel>
|
||||||
Command="{Binding CloseCommand}" />
|
</Grid>
|
||||||
</StackPanel>
|
</GroupBox>
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@ -16,56 +16,59 @@
|
|||||||
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
||||||
TargetType="Window" />
|
TargetType="Window" />
|
||||||
</prism:Dialog.WindowStyle>
|
</prism:Dialog.WindowStyle>
|
||||||
<Grid MouseLeftButtonDown="MouseLeftButtonDown">
|
<GroupBox Header="AC载手动设置"
|
||||||
<TreeView Margin="10">
|
Padding="0,0,0,0">
|
||||||
<TreeViewItem Header="连接状态设置">
|
<Grid MouseLeftButtonDown="MouseLeftButtonDown">
|
||||||
<StackPanel Orientation="Horizontal">
|
<TreeView Margin="10">
|
||||||
<Button Content="连接"
|
<TreeViewItem Header="连接状态设置">
|
||||||
Margin="5"
|
<StackPanel Orientation="Horizontal">
|
||||||
Command="{Binding ConnectCommand}" />
|
<Button Content="连接"
|
||||||
<Button Content="断开"
|
Margin="5"
|
||||||
Margin="5"
|
Command="{Binding ConnectCommand}" />
|
||||||
Command="{Binding DisconnectCommand}" />
|
<Button Content="断开"
|
||||||
</StackPanel>
|
Margin="5"
|
||||||
</TreeViewItem>
|
Command="{Binding DisconnectCommand}" />
|
||||||
|
</StackPanel>
|
||||||
|
</TreeViewItem>
|
||||||
|
|
||||||
<TreeViewItem Header="上下载设置">
|
<TreeViewItem Header="上下载设置">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Content="加载"
|
<Button Content="加载"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{Binding LoadCommand}" />
|
Command="{Binding LoadCommand}" />
|
||||||
<Button Content="卸载"
|
<Button Content="卸载"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{Binding UnloadCommand}" />
|
Command="{Binding UnloadCommand}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</TreeViewItem>
|
</TreeViewItem>
|
||||||
|
|
||||||
<TreeViewItem Header="功率设置">
|
<TreeViewItem Header="功率设置">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Content="读取功率"
|
<Button Content="读取功率"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{Binding ReadPowerCommand}" />
|
Command="{Binding ReadPowerCommand}" />
|
||||||
<Button Content="设置功率"
|
<Button Content="设置功率"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{Binding SetPowerCommand}" />
|
Command="{Binding SetPowerCommand}" />
|
||||||
<Label Content="功率"
|
<Label Content="功率"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
<TextBox Text="{Binding CurrentPowerDisplay}"
|
<TextBox Text="{Binding CurrentPowerDisplay}"
|
||||||
MinWidth="100"
|
MinWidth="100"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
materialDesign:HintAssist.Hint=""
|
materialDesign:HintAssist.Hint=""
|
||||||
VerticalContentAlignment="Center" />
|
VerticalContentAlignment="Center" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</TreeViewItem>
|
</TreeViewItem>
|
||||||
</TreeView>
|
</TreeView>
|
||||||
<StackPanel Grid.Row="2"
|
<StackPanel Grid.Row="2"
|
||||||
VerticalAlignment="Bottom">
|
VerticalAlignment="Bottom">
|
||||||
<Button Content="关闭"
|
<Button Content="关闭"
|
||||||
Width="70"
|
Width="70"
|
||||||
Margin="10"
|
Margin="10"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Command="{Binding CloseCommand}" />
|
Command="{Binding CloseCommand}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
<UserControl x:Class="BOB.Views.ProgressView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:local="clr-namespace:BOB.Views"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="450"
|
|
||||||
d:DesignWidth="800">
|
|
||||||
<Grid Background="Transparent">
|
|
||||||
<StackPanel Width="150"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Margin="0 0 0 100"
|
|
||||||
>
|
|
||||||
<ProgressBar Width="80"
|
|
||||||
Height="80"
|
|
||||||
Margin="20"
|
|
||||||
IsIndeterminate="True"
|
|
||||||
Style="{StaticResource MaterialDesignCircularProgressBar}" />
|
|
||||||
<TextBlock FontSize="30" Text="加载中......" HorizontalAlignment="Center"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@ -252,20 +252,25 @@
|
|||||||
Identifier="Root">
|
Identifier="Root">
|
||||||
<!-- 主内容区 -->
|
<!-- 主内容区 -->
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="29*" />
|
|
||||||
<ColumnDefinition Width="424*" />
|
|
||||||
<ColumnDefinition Width="91*" />
|
|
||||||
<ColumnDefinition Width="57*" />
|
|
||||||
<ColumnDefinition Width="1318*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<ContentControl prism:RegionManager.RegionName="ShellViewManager"
|
<ContentControl prism:RegionManager.RegionName="ShellViewManager"
|
||||||
Grid.ColumnSpan="5" />
|
/>
|
||||||
<Border x:Name="Overlay"
|
<Border x:Name="Overlay"
|
||||||
Background="#40000000"
|
Background="#40000000"
|
||||||
Visibility="Collapsed"
|
Visibility="Collapsed"
|
||||||
Panel.ZIndex="10"
|
Panel.ZIndex="1">
|
||||||
Grid.ColumnSpan="5" />
|
<StackPanel Width="150"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0 0 0 100">
|
||||||
|
<ProgressBar Width="80"
|
||||||
|
Height="80"
|
||||||
|
Margin="20"
|
||||||
|
IsIndeterminate="True"
|
||||||
|
Style="{StaticResource MaterialDesignCircularProgressBar}" />
|
||||||
|
<TextBlock FontSize="30"
|
||||||
|
Text="加载中......"
|
||||||
|
HorizontalAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</materialDesign:DialogHost>
|
</materialDesign:DialogHost>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@ -26,8 +26,6 @@ namespace BOB.Views
|
|||||||
public ShellView(IEventAggregator eventAggregator)
|
public ShellView(IEventAggregator eventAggregator)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
//注册等待消息窗口
|
|
||||||
eventAggregator.GetEvent<WaitingEvent>().Subscribe(ShowWaiting);
|
|
||||||
//注册灰度遮罩层
|
//注册灰度遮罩层
|
||||||
eventAggregator.GetEvent<OverlayEvent>().Subscribe(ShowOverlay);
|
eventAggregator.GetEvent<OverlayEvent>().Subscribe(ShowOverlay);
|
||||||
}
|
}
|
||||||
@ -36,13 +34,7 @@ namespace BOB.Views
|
|||||||
{
|
{
|
||||||
Overlay.Visibility = arg ? Visibility.Visible : Visibility.Collapsed;
|
Overlay.Visibility = arg ? Visibility.Visible : Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
private void ShowWaiting(bool arg)
|
|
||||||
{
|
|
||||||
DialogHost.IsOpen = arg;
|
|
||||||
|
|
||||||
if (DialogHost.IsOpen)
|
|
||||||
DialogHost.DialogContent = new ProgressView();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ColorZone_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
private void ColorZone_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
30
BOB/Views/UpdateInfoView.xaml
Normal file
30
BOB/Views/UpdateInfoView.xaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<UserControl x:Class="BOB.Views.UpdateInfoView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid Margin="20">
|
||||||
|
<ListView ItemsSource="{Binding UpdateList}">
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Margin="5"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<TextBlock Text="{Binding Time}"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Foreground="#673ab7" />
|
||||||
|
<TextBlock Text="{Binding Message}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Margin="0,3,0,10" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</UserControl>
|
||||||
@ -10,16 +10,17 @@ using System.Windows.Documents;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
namespace BOB.Views
|
namespace BOB.Views
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ProgressView.xaml 的交互逻辑
|
/// UpdateInfoView.xaml 的交互逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ProgressView : UserControl
|
public partial class UpdateInfoView : UserControl
|
||||||
{
|
{
|
||||||
public ProgressView()
|
public UpdateInfoView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
<!-- 温度 -->
|
<!-- 温度 -->
|
||||||
<Viewbox Grid.Row="1">
|
<Viewbox Grid.Row="1">
|
||||||
<TextBlock Text="{Binding Temperature, StringFormat='0.00'}"
|
<TextBlock Text="{Binding MonitorValue, StringFormat='0.00'}"
|
||||||
FontSize="40"
|
FontSize="40"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Foreground="{Binding TextColor}"
|
Foreground="{Binding TextColor}"
|
||||||
|
|||||||
12
Common/PubEvent/ChangeCurrentTagEvent.cs
Normal file
12
Common/PubEvent/ChangeCurrentTagEvent.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Common.PubEvent
|
||||||
|
{
|
||||||
|
public class ChangeCurrentTagEvent:PubSubEvent<string>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Common/PubEvent/ConnectionChangeEvent.cs
Normal file
12
Common/PubEvent/ConnectionChangeEvent.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Common.PubEvent
|
||||||
|
{
|
||||||
|
public class ConnectionChangeEvent:PubSubEvent<(string,bool)>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Common/PubEvent/CurveDataEvent.cs
Normal file
13
Common/PubEvent/CurveDataEvent.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Common.PubEvent
|
||||||
|
{
|
||||||
|
public class CurveDataEvent:PubSubEvent<(string, Dictionary<string,double>)>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Common/PubEvent/StartProcessEvent.cs
Normal file
12
Common/PubEvent/StartProcessEvent.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Common.PubEvent
|
||||||
|
{
|
||||||
|
public class StartProcessEvent:PubSubEvent<(string,bool)>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -174,6 +174,43 @@ namespace DeviceCommand.Device
|
|||||||
else if (CurrentDevice == "IT6724CReverse")
|
else if (CurrentDevice == "IT6724CReverse")
|
||||||
await _IT6724CReverse.发送自定义命令(指令, ct);
|
await _IT6724CReverse.发送自定义命令(指令, ct);
|
||||||
}
|
}
|
||||||
|
public virtual async Task<double> 查询实时电压(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
double value = 0;
|
||||||
|
|
||||||
|
if (CurrentDevice == "E36233A")
|
||||||
|
value = await _E36233A.查询电压(ct);
|
||||||
|
else if (CurrentDevice == "IT6724CReverse")
|
||||||
|
value = await _IT6724CReverse.查询实时电压(ct);
|
||||||
|
|
||||||
|
return Math.Round(value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<double> 查询实时电流(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
double value = 0;
|
||||||
|
|
||||||
|
if (CurrentDevice == "E36233A")
|
||||||
|
value = await _E36233A.查询电流(ct);
|
||||||
|
else if (CurrentDevice == "IT6724CReverse")
|
||||||
|
value = await _IT6724CReverse.查询实时电流(ct);
|
||||||
|
|
||||||
|
return Math.Round(value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<double> 查询实时功率(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
double value = 0;
|
||||||
|
|
||||||
|
if (CurrentDevice == "E36233A")
|
||||||
|
value = await _E36233A.查询功率(ct);
|
||||||
|
else if (CurrentDevice == "IT6724CReverse")
|
||||||
|
value = await _IT6724CReverse.查询实时功率(ct);
|
||||||
|
|
||||||
|
return Math.Round(value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,87 +115,146 @@ namespace DeviceCommand.Device
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region 设置命令
|
#region 设置命令(不自动切换通道)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置当前操作通道
|
||||||
|
/// </summary>
|
||||||
|
public async Task 设置通道(int 通道, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync($"INST:NSEL {通道}\n", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询当前通道
|
||||||
|
/// </summary>
|
||||||
|
public async Task<string> 查询当前通道(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync("INST:NSEL?\n", ct);
|
||||||
|
return await ReadAsync(ct: ct);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task 清除输出保护(CancellationToken ct = default)
|
public async Task 清除输出保护(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"PROTection:CLEar\r\n", ct);
|
await SendAsync("OUTP:PROT:CLE\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置电源输出(bool 开关, CancellationToken ct = default)
|
public async Task 设置电源输出(bool 开关, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"OUTPut {(开关 ? 1 : 0)}\r\n", ct);
|
await SendAsync($"OUTP {(开关 ? "ON" : "OFF")}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置为远程模式(CancellationToken ct = default)
|
public async Task 设置为远程模式(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"SYSTem:REMote\r\n", ct);
|
await SendAsync("SYST:REM\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 蜂鸣器测试(CancellationToken ct = default)
|
public async Task 蜂鸣器测试(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"SYSTem:BEEPer\r\n", ct);
|
await SendAsync("SYST:BEEP\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置电流(double 电流, CancellationToken ct = default)
|
public async Task 设置电流(double 电流, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"CURRent {电流}\r\n", ct);
|
await SendAsync($"CURR {电流}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置电流保护OCP电流(double 电流, CancellationToken ct = default)
|
public async Task 设置电流保护OCP电流(double 电流, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"CURRent:PROTection {电流}\r\n", ct);
|
await SendAsync($"CURR:PROT {电流}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置OCP开关(bool 开关, CancellationToken ct = default)
|
public async Task 设置OCP开关(bool 开关, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"CURRent:PROTection:STATe {(开关 ? 1 : 0)}\r\n", ct);
|
await SendAsync($"CURR:PROT:STAT {(开关 ? "ON" : "OFF")}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置电压(double 电压, CancellationToken ct = default)
|
public async Task 设置电压(double 电压, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"VOLTage {电压}\r\n", ct);
|
await SendAsync($"VOLT {电压}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置电压保护OVP电压(double 电压, CancellationToken ct = default)
|
public async Task 设置电压保护OVP电压(double 电压, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"VOLT:PROTection {电压}\r\n", ct);
|
await SendAsync($"VOLT:PROT {电压}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置OVP开关(bool 开关, CancellationToken ct = default)
|
public async Task 设置OVP开关(bool 开关, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"VOLT:PROTection:STATe {(开关 ? 1 : 0)}\r\n", ct);
|
await SendAsync($"VOLT:PROT:STAT {(开关 ? "ON" : "OFF")}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置功率保护功率(double 电压, CancellationToken ct = default)
|
public async Task 设置功率保护功率(double 功率值, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"POWer:PROTection {电压}\r\n", ct);
|
await SendAsync($"POW:PROT {功率值}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置功率保护开关(bool 开关, CancellationToken ct = default)
|
public async Task 设置功率保护开关(bool 开关, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"POWer:PROTection:STATe {(开关 ? 1 : 0)}\r\n", ct);
|
await SendAsync($"POW:PROT:STAT {(开关 ? "ON" : "OFF")}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置电流斜率(double 上升斜率, double 下降斜率, CancellationToken ct = default)
|
public async Task 设置电流斜率(double 上升斜率, double 下降斜率, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"CURRent:SLEW {上升斜率},{下降斜率}\r\n", ct);
|
await SendAsync($"CURR:SLEW:UP {上升斜率}\n", ct);
|
||||||
|
await SendAsync($"CURR:SLEW:DOWN {下降斜率}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 设置电压斜率(double 上升斜率, double 下降斜率, CancellationToken ct = default)
|
public async Task 设置电压斜率(double 上升斜率, double 下降斜率, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"VOLTage:SLEW {上升斜率},{下降斜率}\r\n", ct);
|
await SendAsync($"VOLT:SLEW:UP {上升斜率}\n", ct);
|
||||||
|
await SendAsync($"VOLT:SLEW:DOWN {下降斜率}\n", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task 发送自定义命令(string 指令, CancellationToken ct = default)
|
public async Task 发送自定义命令(string 指令, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"{指令}\r\n", ct);
|
await SendAsync($"{指令}\n", ct);
|
||||||
}
|
}
|
||||||
public virtual async Task<string> 查询设备信息(CancellationToken ct = default)
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询设备基本信息
|
||||||
|
/// </summary>
|
||||||
|
public async Task<string> 查询设备信息(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync("*IDN?\r\n", ct);
|
await SendAsync("*IDN?\n", ct);
|
||||||
return await ReadAsync(ct: ct);
|
return await ReadAsync(ct: ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 查询命令
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询当前电压测量值
|
||||||
|
/// </summary>
|
||||||
|
public async Task<double> 查询电压(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync("MEAS:VOLT?\n", ct);
|
||||||
|
string result = await ReadAsync(ct: ct);
|
||||||
|
return double.Parse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询当前电流测量值
|
||||||
|
/// </summary>
|
||||||
|
public async Task<double> 查询电流(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync("MEAS:CURR?\n", ct);
|
||||||
|
string result = await ReadAsync(ct: ct);
|
||||||
|
return double.Parse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询当前功率测量值
|
||||||
|
/// </summary>
|
||||||
|
public async Task<double> 查询功率(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync("MEAS:POW?\n", ct);
|
||||||
|
string result = await ReadAsync(ct: ct);
|
||||||
|
return double.Parse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ namespace DeviceCommand.Device
|
|||||||
|
|
||||||
public override async Task<bool> ConnectAsync(CancellationToken ct = default)
|
public override async Task<bool> ConnectAsync(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
|
await commLock.WaitAsync(ct);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (SerialPort.IsOpen)
|
if (SerialPort.IsOpen)
|
||||||
@ -48,7 +49,7 @@ namespace DeviceCommand.Device
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
commLock.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void Close()
|
public override void Close()
|
||||||
|
|||||||
@ -25,6 +25,7 @@ namespace DeviceCommand.Device
|
|||||||
|
|
||||||
public override async Task<bool> ConnectAsync(CancellationToken ct = default)
|
public override async Task<bool> ConnectAsync(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
|
await commLock.WaitAsync(ct);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (SerialPort.IsOpen)
|
if (SerialPort.IsOpen)
|
||||||
@ -46,7 +47,7 @@ namespace DeviceCommand.Device
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
commLock.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void Close()
|
public override void Close()
|
||||||
@ -171,7 +172,35 @@ namespace DeviceCommand.Device
|
|||||||
await SendAsync("*IDN?\r\n", ct);
|
await SendAsync("*IDN?\r\n", ct);
|
||||||
return await ReadAsync(ct: ct);
|
return await ReadAsync(ct: ct);
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 查询实际输出电流(单位:A)
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task<double> 查询实时电流(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync("MEASure:CURRent?\r\n", ct);
|
||||||
|
var result = await ReadAsync(ct: ct);
|
||||||
|
return Convert.ToDouble(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询实际输出电压(单位:V)
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task<double> 查询实时电压(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync("MEASure:VOLTage?\r\n", ct);
|
||||||
|
var result = await ReadAsync(ct: ct);
|
||||||
|
return Convert.ToDouble(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询实际输出功率(单位:W)
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task<double> 查询实时功率(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await SendAsync("MEASure:POWer?\r\n", ct);
|
||||||
|
var result = await ReadAsync(ct: ct);
|
||||||
|
return Convert.ToDouble(result);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
14
Model/UpdateInfoModel.cs
Normal file
14
Model/UpdateInfoModel.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
public class UpdateInfoModel
|
||||||
|
{
|
||||||
|
public string Message { get; set; }
|
||||||
|
public string Time { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ using BOB.Views;
|
|||||||
using BOB.Views.Dialogs;
|
using BOB.Views.Dialogs;
|
||||||
using Prism.Ioc;
|
using Prism.Ioc;
|
||||||
using ProcessManager.ViewModels;
|
using ProcessManager.ViewModels;
|
||||||
|
using ProcessManager.Views;
|
||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
@ -23,12 +24,18 @@ namespace ProcessManager
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
|
var regionManager = Container.Resolve<IRegionManager>();
|
||||||
|
regionManager.RequestNavigate("MainRegion", "Menu");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||||||
{
|
{
|
||||||
containerRegistry.RegisterForNavigation<MainWindow, PMainViewModel>();
|
containerRegistry.RegisterForNavigation<MainWindow, PMainViewModel>();
|
||||||
|
containerRegistry.RegisterForNavigation<MenuView, MenuViewModel>("Menu");
|
||||||
|
containerRegistry.RegisterForNavigation<DevicesView, DevicesViewModel>("DeviceOne");
|
||||||
|
containerRegistry.RegisterForNavigation<DeviceTwoView, DevicesViewModel>("DeviceTwo");
|
||||||
|
containerRegistry.RegisterForNavigation<DeviceThreeView, DevicesViewModel>("DeviceThree");
|
||||||
|
containerRegistry.RegisterForNavigation<DeviceOther, DevicesViewModel>("Other");
|
||||||
containerRegistry.RegisterDialog<Setting, SettingViewModel>("Setting");
|
containerRegistry.RegisterDialog<Setting, SettingViewModel>("Setting");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,8 +8,24 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<COMReference Include="{215d64d2-031c-33c7-96e3-61794cd1ee61}">
|
||||||
|
<WrapperTool>tlbimp</WrapperTool>
|
||||||
|
<VersionMinor>0</VersionMinor>
|
||||||
|
<VersionMajor>2</VersionMajor>
|
||||||
|
<Guid>215d64d2-031c-33c7-96e3-61794cd1ee61</Guid>
|
||||||
|
</COMReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\BOB\BOB.csproj" />
|
<ProjectReference Include="..\BOB\BOB.csproj" />
|
||||||
|
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="WindowsFormsIntegration">
|
||||||
|
<HintPath>..\..\..\WindowsFormsIntegration.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
73
ProcessManager/ViewModels/DevicesViewModel.cs
Normal file
73
ProcessManager/ViewModels/DevicesViewModel.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
using Common.PubEvent;
|
||||||
|
using OxyPlot;
|
||||||
|
using ProcessManager.Helpers;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace ProcessManager.ViewModels
|
||||||
|
{
|
||||||
|
public class DevicesViewModel:BindableBase,INavigationAware
|
||||||
|
{
|
||||||
|
public ICommand WindowLoadedCommand { get; set; }
|
||||||
|
public IEventAggregator _eventAggregator { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
private UserControl? _currentView;
|
||||||
|
private System.Windows.Forms.Panel? _host;
|
||||||
|
|
||||||
|
public DevicesViewModel(IContainerProvider containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
_eventAggregator.GetEvent<StartProcessEvent>().Subscribe(GetProcess);
|
||||||
|
WindowLoadedCommand =new DelegateCommand(OnWindowLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetProcess((string exeName, bool isStart) msg)
|
||||||
|
{
|
||||||
|
if(Title!= msg.exeName) return;
|
||||||
|
if (_currentView == null) return;
|
||||||
|
if (!msg.isStart) return;
|
||||||
|
WindowEmbedHelper.FindAndEmbedWindow(msg.exeName, _host);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnWindowLoaded()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#region 导航
|
||||||
|
public bool IsNavigationTarget(NavigationContext navigationContext)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNavigatedFrom(NavigationContext navigationContext)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNavigatedTo(NavigationContext navigationContext)
|
||||||
|
{
|
||||||
|
Title= navigationContext.Parameters.GetValue<string>("Title");
|
||||||
|
string viewName = navigationContext.Parameters.GetValue<string>("viewName");
|
||||||
|
_currentView = navigationContext.NavigationService.Region .ActiveViews .FirstOrDefault() as UserControl;
|
||||||
|
if (_currentView != null)
|
||||||
|
{
|
||||||
|
// 反射拿 Host 属性
|
||||||
|
var hostProp = _currentView.GetType().GetProperty("Host");
|
||||||
|
_host = hostProp?.GetValue(_currentView) as System.Windows.Forms.Panel;
|
||||||
|
}
|
||||||
|
_eventAggregator.GetEvent<ChangeCurrentTagEvent>()
|
||||||
|
.Publish(!string.IsNullOrEmpty(viewName) ? viewName : Title);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
163
ProcessManager/ViewModels/MenuViewModel.cs
Normal file
163
ProcessManager/ViewModels/MenuViewModel.cs
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
using Azure;
|
||||||
|
using BOB;
|
||||||
|
using Common.PubEvent;
|
||||||
|
using ProcessManager.Helpers;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace ProcessManager.ViewModels
|
||||||
|
{
|
||||||
|
public class MenuViewModel : BindableBase, INavigationAware
|
||||||
|
{
|
||||||
|
private ObservableCollection<SystemConfig> _configList;
|
||||||
|
|
||||||
|
public ObservableCollection<SystemConfig> ConfigList
|
||||||
|
{
|
||||||
|
get => _configList;
|
||||||
|
set => SetProperty(ref _configList, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly IDialogService _dialogService;
|
||||||
|
private readonly IRegionManager _regionManager;
|
||||||
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private Dictionary<string, Process> ProcessDic { get; set; } = new Dictionary<string, Process>();
|
||||||
|
public ICommand StartCommand { get; set; }
|
||||||
|
public ICommand EditCommand { get; set; }
|
||||||
|
public ICommand WindowLoadedCommand { get; set; }
|
||||||
|
|
||||||
|
public MenuViewModel(IContainerProvider containerProvider)
|
||||||
|
{
|
||||||
|
_dialogService = containerProvider.Resolve<IDialogService>();
|
||||||
|
_regionManager = containerProvider.Resolve<IRegionManager>();
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
EditCommand = new DelegateCommand<string>(OnEdit);
|
||||||
|
StartCommand = new DelegateCommand<string>(OnStart);
|
||||||
|
WindowLoadedCommand = new DelegateCommand(OnWindowLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void OnWindowLoaded()
|
||||||
|
{
|
||||||
|
if (ConfigList != null) ConfigList.Clear();
|
||||||
|
var JSONFiles = Directory.GetFiles(JsonHelper.SystemPath, "*.json");
|
||||||
|
foreach (var file in JSONFiles)
|
||||||
|
{
|
||||||
|
JsonHelper.ConfigFile = file;
|
||||||
|
var config = JsonHelper.LoadFromFile();
|
||||||
|
if (ConfigList == null)
|
||||||
|
{
|
||||||
|
ConfigList = new ObservableCollection<SystemConfig>();
|
||||||
|
}
|
||||||
|
ConfigList.Add(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStart(string deviceName)
|
||||||
|
{
|
||||||
|
if (ProcessDic.ContainsKey(deviceName))
|
||||||
|
{
|
||||||
|
MessageBox.Show("进程已启动");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string currentDir = Environment.CurrentDirectory;
|
||||||
|
string exePath = Path.Combine(currentDir, "BOB.exe");
|
||||||
|
if (!File.Exists(exePath))
|
||||||
|
{
|
||||||
|
MessageBox.Show($"未找到文件: {exePath}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = exePath,
|
||||||
|
Arguments = deviceName,
|
||||||
|
UseShellExecute = true
|
||||||
|
};
|
||||||
|
var configToSave = ConfigList.FirstOrDefault(x => x.Title == deviceName);
|
||||||
|
if (configToSave != null)
|
||||||
|
{
|
||||||
|
JsonHelper.ConfigFile = Path.Combine(JsonHelper.SystemPath, $"{deviceName}.json");
|
||||||
|
JsonHelper.SaveToFile(configToSave);
|
||||||
|
}
|
||||||
|
var process = Process.Start(startInfo);
|
||||||
|
process.EnableRaisingEvents = true;
|
||||||
|
process.Exited += (s, args) =>
|
||||||
|
{
|
||||||
|
ProcessDic.Remove(deviceName);
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
OnWindowLoaded();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
ProcessDic.Add(deviceName, process);
|
||||||
|
string viewName = deviceName switch
|
||||||
|
{
|
||||||
|
"设备1" => "DeviceOne",
|
||||||
|
"设备2" => "DeviceTwo",
|
||||||
|
"设备3" => "DeviceThree",
|
||||||
|
_ => "Other"
|
||||||
|
};
|
||||||
|
var parameters = new NavigationParameters
|
||||||
|
{
|
||||||
|
{ "Title", deviceName },
|
||||||
|
{ "viewName", viewName },
|
||||||
|
};
|
||||||
|
_regionManager.RequestNavigate("MainRegion", viewName, parameters);
|
||||||
|
_eventAggregator.GetEvent<StartProcessEvent>().Publish((deviceName, true));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"启动失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEdit(string deviceName)
|
||||||
|
{
|
||||||
|
if (ProcessDic.ContainsKey(deviceName))
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先关闭进程再进行编辑");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JsonHelper.ConfigFile = Path.Combine(JsonHelper.SystemPath, $"{deviceName}.json");
|
||||||
|
var ConfigSystem = JsonHelper.LoadFromFile();
|
||||||
|
var parameters = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "SystemConfig", ConfigSystem },
|
||||||
|
{ "Title", deviceName }
|
||||||
|
};
|
||||||
|
|
||||||
|
_dialogService.ShowDialog("Setting", parameters, r =>
|
||||||
|
{
|
||||||
|
if (r.Result == ButtonResult.OK)
|
||||||
|
{
|
||||||
|
// 用户点击 OK
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public bool IsNavigationTarget(NavigationContext navigationContext)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNavigatedFrom(NavigationContext navigationContext)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNavigatedTo(NavigationContext navigationContext)
|
||||||
|
{
|
||||||
|
_eventAggregator.GetEvent<ChangeCurrentTagEvent>().Publish("Menu");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,9 @@
|
|||||||
using BOB;
|
using Azure;
|
||||||
|
using BOB;
|
||||||
|
using Common.PubEvent;
|
||||||
using MahApps.Metro.Controls;
|
using MahApps.Metro.Controls;
|
||||||
|
using Prism.Ioc;
|
||||||
|
using ProcessManager.Helpers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -15,111 +19,71 @@ namespace ProcessManager.ViewModels
|
|||||||
{
|
{
|
||||||
public class PMainViewModel:BindableBase
|
public class PMainViewModel:BindableBase
|
||||||
{
|
{
|
||||||
private ObservableCollection<SystemConfig> _configList;
|
private string _currentTag;
|
||||||
|
public string CurrentTag
|
||||||
public ObservableCollection<SystemConfig> ConfigList
|
|
||||||
{
|
{
|
||||||
get => _configList;
|
get => _currentTag;
|
||||||
set => SetProperty(ref _configList, value);
|
set => SetProperty(ref _currentTag, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
private Dictionary<string, Process> ProcessDic { get; set; } = new Dictionary<string, Process>();
|
private IRegionManager _regionManager;
|
||||||
public ICommand StartCommand { get; set; }
|
private IEventAggregator _eventAggregator;
|
||||||
public ICommand EditCommand { get; set; }
|
public ICommand MinimizeCommand { get; set; }
|
||||||
public ICommand WindowLoadedCommand { get; set; }
|
public ICommand MaximizeCommand { get; set; }
|
||||||
public PMainViewModel(IDialogService dialogService)
|
public ICommand CloseCommand { get; set; }
|
||||||
|
public ICommand NavigateToMenuCommand { get; set; }
|
||||||
|
public ICommand NavigateToDeviceCommand { get; set; }
|
||||||
|
public PMainViewModel(IContainerProvider containerProvider)
|
||||||
{
|
{
|
||||||
_dialogService = dialogService;
|
containerProvider = containerProvider;
|
||||||
EditCommand=new DelegateCommand<string>(OnEdit);
|
_eventAggregator=containerProvider.Resolve<IEventAggregator>();
|
||||||
StartCommand = new DelegateCommand<string>(OnStart);
|
_dialogService = containerProvider.Resolve<IDialogService>();
|
||||||
WindowLoadedCommand = new DelegateCommand(OnWindowLoaded);
|
_regionManager = containerProvider.Resolve<IRegionManager>();
|
||||||
|
NavigateToMenuCommand = new DelegateCommand(NavigateToMenu);
|
||||||
|
NavigateToDeviceCommand = new DelegateCommand<string>(NavigateToDevice);
|
||||||
|
MinimizeCommand = new DelegateCommand<Window>(MinimizeWindow);
|
||||||
|
MaximizeCommand = new DelegateCommand<Window>(MaximizeWindow);
|
||||||
|
CloseCommand = new DelegateCommand<Window>(CloseWindow);
|
||||||
|
_eventAggregator.GetEvent<ChangeCurrentTagEvent>().Subscribe(ChangeCurrentTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnWindowLoaded()
|
private void ChangeCurrentTag(string obj)
|
||||||
{
|
{
|
||||||
if (ConfigList != null) ConfigList.Clear();
|
CurrentTag = obj;
|
||||||
var JSONFiles = Directory.GetFiles(JsonHelper.SystemPath, "*.json");
|
|
||||||
foreach(var file in JSONFiles)
|
|
||||||
{
|
|
||||||
JsonHelper.ConfigFile = file;
|
|
||||||
var config = JsonHelper.LoadFromFile();
|
|
||||||
if(ConfigList==null)
|
|
||||||
{
|
|
||||||
ConfigList = new ObservableCollection<SystemConfig>();
|
|
||||||
}
|
|
||||||
ConfigList.Add(config);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStart(string deviceName)
|
private void NavigateToDevice(string page)
|
||||||
{
|
{
|
||||||
if (ProcessDic.ContainsKey(deviceName))
|
var parameters = new NavigationParameters
|
||||||
{
|
|
||||||
MessageBox.Show("进程已启动");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string currentDir = Environment.CurrentDirectory;
|
|
||||||
string exePath = Path.Combine(currentDir, "BOB.exe");
|
|
||||||
if (!File.Exists(exePath))
|
|
||||||
{
|
{
|
||||||
MessageBox.Show($"未找到文件: {exePath}");
|
{ "Title", page },
|
||||||
return;
|
|
||||||
}
|
|
||||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = exePath,
|
|
||||||
Arguments = deviceName,
|
|
||||||
UseShellExecute = true
|
|
||||||
};
|
};
|
||||||
var configToSave = ConfigList.FirstOrDefault(x => x.Title == deviceName);
|
_regionManager.RequestNavigate("MainRegion", page,parameters);
|
||||||
if (configToSave != null)
|
|
||||||
{
|
|
||||||
JsonHelper.ConfigFile = Path.Combine(JsonHelper.SystemPath, $"{deviceName}.json");
|
|
||||||
JsonHelper.SaveToFile(configToSave);
|
|
||||||
}
|
|
||||||
var process = Process.Start(startInfo);
|
|
||||||
process.EnableRaisingEvents = true;
|
|
||||||
process.Exited += (s, args) =>
|
|
||||||
{
|
|
||||||
ProcessDic.Remove(deviceName);
|
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
|
||||||
{
|
|
||||||
OnWindowLoaded();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
ProcessDic.Add(deviceName, process);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"启动失败: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEdit(string deviceName)
|
private void NavigateToMenu()
|
||||||
{
|
{
|
||||||
if (ProcessDic.ContainsKey(deviceName))
|
_regionManager.RequestNavigate("MainRegion", "Menu");
|
||||||
{
|
|
||||||
MessageBox.Show("请先关闭进程再进行编辑");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JsonHelper.ConfigFile = Path.Combine(JsonHelper.SystemPath, $"{deviceName}.json");
|
|
||||||
var ConfigSystem = JsonHelper.LoadFromFile();
|
|
||||||
var parameters = new DialogParameters
|
|
||||||
{
|
|
||||||
{ "SystemConfig", ConfigSystem },
|
|
||||||
{ "Title", deviceName }
|
|
||||||
};
|
|
||||||
|
|
||||||
_dialogService.ShowDialog("Setting", parameters, r =>
|
|
||||||
{
|
|
||||||
if (r.Result == ButtonResult.OK)
|
|
||||||
{
|
|
||||||
// 用户点击 OK
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
private void MinimizeWindow(Window window)
|
||||||
|
{
|
||||||
|
if (window != null)
|
||||||
|
window.WindowState = WindowState.Minimized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MaximizeWindow(Window window)
|
||||||
|
{
|
||||||
|
if (window != null)
|
||||||
|
{
|
||||||
|
window.WindowState = window.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseWindow(Window window)
|
||||||
|
{
|
||||||
|
window?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
ProcessManager/Views/DeviceOther.xaml
Normal file
20
ProcessManager/Views/DeviceOther.xaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<UserControl x:Class="ProcessManager.Views.DeviceOther"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:winform="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="Loaded">
|
||||||
|
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>
|
||||||
|
<Grid Name="MainGrid">
|
||||||
|
<WindowsFormsHost>
|
||||||
|
<winform:Panel x:Name="PanelHost"></winform:Panel>
|
||||||
|
</WindowsFormsHost>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
29
ProcessManager/Views/DeviceOther.xaml.cs
Normal file
29
ProcessManager/Views/DeviceOther.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace ProcessManager.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DeviceOther.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class DeviceOther : UserControl
|
||||||
|
{
|
||||||
|
public System.Windows.Forms.Panel Host => PanelHost;
|
||||||
|
public DeviceOther()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
ProcessManager/Views/DeviceThreeView.xaml
Normal file
20
ProcessManager/Views/DeviceThreeView.xaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<UserControl x:Class="ProcessManager.DeviceThreeView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:winform="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="Loaded">
|
||||||
|
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>
|
||||||
|
<Grid Name="MainGrid">
|
||||||
|
<WindowsFormsHost>
|
||||||
|
<winform:Panel x:Name="PanelHost"></winform:Panel>
|
||||||
|
</WindowsFormsHost>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
29
ProcessManager/Views/DeviceThreeView.xaml.cs
Normal file
29
ProcessManager/Views/DeviceThreeView.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace ProcessManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DeviceThreeView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class DeviceThreeView : UserControl
|
||||||
|
{
|
||||||
|
public System.Windows.Forms.Panel Host => PanelHost;
|
||||||
|
public DeviceThreeView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
ProcessManager/Views/DeviceTwoView.xaml
Normal file
20
ProcessManager/Views/DeviceTwoView.xaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<UserControl x:Class="ProcessManager.DeviceTwoView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:winform="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="Loaded">
|
||||||
|
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>
|
||||||
|
<Grid Name="MainGrid">
|
||||||
|
<WindowsFormsHost>
|
||||||
|
<winform:Panel x:Name="PanelHost"></winform:Panel>
|
||||||
|
</WindowsFormsHost>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
29
ProcessManager/Views/DeviceTwoView.xaml.cs
Normal file
29
ProcessManager/Views/DeviceTwoView.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace ProcessManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DeviceTwoView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class DeviceTwoView : UserControl
|
||||||
|
{
|
||||||
|
public System.Windows.Forms.Panel Host => PanelHost;
|
||||||
|
public DeviceTwoView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
ProcessManager/Views/DevicesView.xaml
Normal file
20
ProcessManager/Views/DevicesView.xaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<UserControl x:Class="ProcessManager.DevicesView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:winform="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="Loaded">
|
||||||
|
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>
|
||||||
|
<Grid Name="MainGrid">
|
||||||
|
<WindowsFormsHost>
|
||||||
|
<winform:Panel x:Name="PanelHost"></winform:Panel>
|
||||||
|
</WindowsFormsHost>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
29
ProcessManager/Views/DevicesView.xaml.cs
Normal file
29
ProcessManager/Views/DevicesView.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace ProcessManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DevicesView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class DevicesView : UserControl
|
||||||
|
{
|
||||||
|
public System.Windows.Forms.Panel Host => PanelHost;
|
||||||
|
public DevicesView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
213
ProcessManager/Views/MainWindow.xaml
Normal file
213
ProcessManager/Views/MainWindow.xaml
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
<Window x:Class="ProcessManager.MainWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="hMetroWindowttp://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
|
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
|
xmlns:local="clr-namespace:ProcessManager"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
WindowStyle="None"
|
||||||
|
Title="MainWindow" Height="600" Width="1000">
|
||||||
|
<WindowChrome.WindowChrome>
|
||||||
|
<WindowChrome GlassFrameThickness="-1" />
|
||||||
|
</WindowChrome.WindowChrome>
|
||||||
|
|
||||||
|
<materialDesign:DialogHost x:Name="MainDialogHost">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<materialDesign:ColorZone Mode="PrimaryMid"
|
||||||
|
Background="#FF6200EE">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto" />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition Width="auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Menu Grid.Column="0"
|
||||||
|
Background="Transparent"
|
||||||
|
Foreground="White"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="菜单"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding DataContext.NavigateToMenuCommand, RelativeSource={RelativeSource AncestorType=Window}}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Menu"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
<MenuItem.Style>
|
||||||
|
<Style TargetType="MenuItem"
|
||||||
|
BasedOn="{StaticResource {x:Type MenuItem}}">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="Transparent" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding DataContext.CurrentTag, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
Value="Menu">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="#FFBB86FC" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</MenuItem.Style>
|
||||||
|
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="设备一"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding DataContext.NavigateToDeviceCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
CommandParameter="DeviceOne">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Menu"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
<MenuItem.Style>
|
||||||
|
<Style TargetType="MenuItem"
|
||||||
|
BasedOn="{StaticResource {x:Type MenuItem}}">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="Transparent" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding DataContext.CurrentTag, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
Value="DeviceOne">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="#FFBB86FC" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</MenuItem.Style>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="设备二"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding DataContext.NavigateToDeviceCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
CommandParameter="DeviceTwo">
|
||||||
|
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Menu"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
<MenuItem.Style>
|
||||||
|
<Style TargetType="MenuItem"
|
||||||
|
BasedOn="{StaticResource {x:Type MenuItem}}">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="Transparent" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding DataContext.CurrentTag, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
Value="DeviceTwo">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="#FFBB86FC" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</MenuItem.Style>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="设备三"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding DataContext.NavigateToDeviceCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
CommandParameter="DeviceThree">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Menu"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
<MenuItem.Style>
|
||||||
|
<Style TargetType="MenuItem"
|
||||||
|
BasedOn="{StaticResource {x:Type MenuItem}}">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="Transparent" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding DataContext.CurrentTag, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
Value="DeviceThree">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="#FFBB86FC" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</MenuItem.Style>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="环境箱和水冷机"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding DataContext.NavigateToDeviceCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
CommandParameter="Other">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Menu"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
<MenuItem.Style>
|
||||||
|
<Style TargetType="MenuItem"
|
||||||
|
BasedOn="{StaticResource {x:Type MenuItem}}">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="Transparent" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding DataContext.CurrentTag, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
|
Value="Other">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="#FFBB86FC" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</MenuItem.Style>
|
||||||
|
</MenuItem>
|
||||||
|
|
||||||
|
</Menu>
|
||||||
|
|
||||||
|
<Border Grid.Column="1"/>
|
||||||
|
<Menu Grid.Column="2"
|
||||||
|
Margin="0 0 20 0">
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="最小化"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding MinimizeCommand}"
|
||||||
|
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Minimize"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="最大化"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding MaximizeCommand}"
|
||||||
|
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Maximize"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
|
||||||
|
<MenuItem FontSize="14"
|
||||||
|
Height="50"
|
||||||
|
Header="关闭"
|
||||||
|
Foreground="White"
|
||||||
|
Command="{Binding CloseCommand}"
|
||||||
|
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Close"
|
||||||
|
Foreground="White" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:ColorZone>
|
||||||
|
|
||||||
|
<ContentControl Grid.Row="1"
|
||||||
|
prism:RegionManager.RegionName="MainRegion"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</materialDesign:DialogHost>
|
||||||
|
|
||||||
|
</Window>
|
||||||
@ -12,7 +12,7 @@ namespace ProcessManager
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for MainWindow.xaml
|
/// Interaction logic for MainWindow.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MainWindow : MetroWindow
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
@ -1,24 +1,23 @@
|
|||||||
<mah:MetroWindow x:Class="ProcessManager.MainWindow"
|
<UserControl x:Class="ProcessManager.MenuView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="hMetroWindowttp://schemas.microsoft.com/expression/blend/2008"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
xmlns:local="clr-namespace:ProcessManager"
|
||||||
xmlns:local="clr-namespace:ProcessManager"
|
mc:Ignorable="d"
|
||||||
mc:Ignorable="d"
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
Title="MainWindow" Height="600" Width="1000">
|
|
||||||
|
|
||||||
<i:Interaction.Triggers>
|
<i:Interaction.Triggers>
|
||||||
<i:EventTrigger EventName="Loaded">
|
<i:EventTrigger EventName="Loaded">
|
||||||
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
|
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
|
||||||
</i:EventTrigger>
|
</i:EventTrigger>
|
||||||
</i:Interaction.Triggers>
|
</i:Interaction.Triggers>
|
||||||
|
<Grid>
|
||||||
<materialDesign:DialogHost x:Name="MainDialogHost">
|
<ItemsControl ItemsSource="{Binding ConfigList}"
|
||||||
<ItemsControl ItemsSource="{Binding ConfigList}">
|
Grid.Row="1">
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<WrapPanel IsItemsHost="True"
|
<WrapPanel IsItemsHost="True"
|
||||||
@ -27,7 +26,7 @@
|
|||||||
</ItemsControl.ItemsPanel>
|
</ItemsControl.ItemsPanel>
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<materialDesign:Card Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}"
|
<materialDesign:Card Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
Width="220"
|
Width="220"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Padding="8"
|
Padding="8"
|
||||||
@ -63,11 +62,11 @@
|
|||||||
<MenuItem Header="编辑"
|
<MenuItem Header="编辑"
|
||||||
Command="{Binding EditCommand}"
|
Command="{Binding EditCommand}"
|
||||||
CommandParameter="{Binding PlacementTarget.DataContext.Title,
|
CommandParameter="{Binding PlacementTarget.DataContext.Title,
|
||||||
RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
|
RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
|
||||||
<MenuItem Header="启动"
|
<MenuItem Header="启动"
|
||||||
Command="{Binding StartCommand}"
|
Command="{Binding StartCommand}"
|
||||||
CommandParameter="{Binding PlacementTarget.DataContext.Title,
|
CommandParameter="{Binding PlacementTarget.DataContext.Title,
|
||||||
RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
|
RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
|
||||||
|
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</materialDesign:Card.ContextMenu>
|
</materialDesign:Card.ContextMenu>
|
||||||
@ -75,5 +74,5 @@
|
|||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
</materialDesign:DialogHost>
|
</Grid>
|
||||||
</mah:MetroWindow>
|
</UserControl>
|
||||||
28
ProcessManager/Views/MenuView.xaml.cs
Normal file
28
ProcessManager/Views/MenuView.xaml.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace ProcessManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// MenuView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class MenuView : UserControl
|
||||||
|
{
|
||||||
|
public MenuView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
<UserControl x:Class="ProcessManager.Setting"
|
<UserControl x:Class="ProcessManager.Setting"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:local="clr-namespace:ProcessManager"
|
xmlns:local="clr-namespace:ProcessManager"
|
||||||
MinHeight="250"
|
MinHeight="250"
|
||||||
93
ProcessManager/WindowEmbedHelper.cs
Normal file
93
ProcessManager/WindowEmbedHelper.cs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Interop;
|
||||||
|
|
||||||
|
namespace ProcessManager.Helpers
|
||||||
|
{
|
||||||
|
public static class WindowEmbedHelper
|
||||||
|
{
|
||||||
|
private const int GWL_STYLE = -16;
|
||||||
|
private const long WS_CAPTION = 0x00C00000;
|
||||||
|
private const long WS_THICKFRAME = 0x00040000;
|
||||||
|
private const long WS_CHILD = 0x40000000;
|
||||||
|
|
||||||
|
public static void FindAndEmbedWindow(string windowTitle, System.Windows.Forms.Panel panel, int timeoutMs = 10000)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
IntPtr hWnd = IntPtr.Zero;
|
||||||
|
int elapsed = 0;
|
||||||
|
|
||||||
|
while (elapsed < timeoutMs)
|
||||||
|
{
|
||||||
|
hWnd = FindWindow(null, windowTitle);
|
||||||
|
|
||||||
|
if (hWnd != IntPtr.Zero)
|
||||||
|
break;
|
||||||
|
|
||||||
|
await Task.Delay(200);
|
||||||
|
elapsed += 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hWnd == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
MessageBox.Show($"在 {timeoutMs / 1000.0}s 内未找到窗口:{windowTitle}");
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
EmbedWindow(hWnd, panel);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EmbedWindow(IntPtr childHwnd, System.Windows.Forms.Panel panel)
|
||||||
|
{
|
||||||
|
IntPtr parentHwnd = panel.Handle;
|
||||||
|
|
||||||
|
// 设定父窗口
|
||||||
|
SetParent(childHwnd, parentHwnd);
|
||||||
|
|
||||||
|
// 去掉标题栏
|
||||||
|
long style = GetWindowLong(childHwnd, GWL_STYLE);
|
||||||
|
style &= ~WS_CAPTION;
|
||||||
|
style &= ~WS_THICKFRAME;
|
||||||
|
style |= WS_CHILD;
|
||||||
|
SetWindowLong(childHwnd, GWL_STYLE, style);
|
||||||
|
|
||||||
|
ResizeEmbeddedWindow(childHwnd, panel);
|
||||||
|
|
||||||
|
// 自动resize
|
||||||
|
panel.Resize -= (s, e) => ResizeEmbeddedWindow(childHwnd, panel);
|
||||||
|
panel.Resize += (s, e) => ResizeEmbeddedWindow(childHwnd, panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ResizeEmbeddedWindow(IntPtr hWnd, System.Windows.Forms.Panel panel)
|
||||||
|
{
|
||||||
|
MoveWindow(hWnd, 0, 0, panel.Width, panel.Height, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr FindWindow(string? lpClassName, string? lpWindowName);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int W, int H, bool repaint);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern long GetWindowLong(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern long SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user