设备编辑1
This commit is contained in:
@@ -67,29 +67,44 @@ namespace TestingModule.ViewModels
|
|||||||
private ScopedContext _ScopedContext { get; set; }
|
private ScopedContext _ScopedContext { get; set; }
|
||||||
private readonly SystemConfig _systemConfig;
|
private readonly SystemConfig _systemConfig;
|
||||||
private readonly GlobalInfo _globalInfo;
|
private readonly GlobalInfo _globalInfo;
|
||||||
|
private readonly DeviceManager _deviceManager;
|
||||||
#region 命令
|
#region 命令
|
||||||
public ICommand ParameterAddCommand { get; set; }
|
public ICommand ParameterAddCommand { get; set; }
|
||||||
public ICommand ParameterEditCommand { get; set; }
|
public ICommand ParameterEditCommand { get; set; }
|
||||||
public ICommand ParameterDeleteCommand { get; set; }
|
public ICommand ParameterDeleteCommand { get; set; }
|
||||||
public ICommand DeviceEditCommand { get; set; }
|
public ICommand DeviceEditCommand { get; set; }
|
||||||
public ICommand ReconnnectCommand { get; set; }
|
public ICommand ReConnectCommand { get; set; }
|
||||||
public ICommand CloseCommand { get; set; }
|
public ICommand CloseCommand { get; set; }
|
||||||
|
public ICommand LoadedCommand { get; set; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public ParametersManagerViewModel(IContainerProvider containerProvider, ScopedContext scopedContext, SystemConfig systemConfig, GlobalInfo globalInfo) : base(containerProvider)
|
public ParametersManagerViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
{
|
{
|
||||||
_ScopedContext = scopedContext;
|
|
||||||
_systemConfig = systemConfig;
|
_ScopedContext = containerProvider.Resolve<ScopedContext>();
|
||||||
_globalInfo = globalInfo;
|
_systemConfig = containerProvider.Resolve<SystemConfig>();
|
||||||
|
_deviceManager = containerProvider.Resolve<DeviceManager>();
|
||||||
|
_globalInfo = containerProvider.Resolve<GlobalInfo>();
|
||||||
Program = _ScopedContext.Program;
|
Program = _ScopedContext.Program;
|
||||||
ParameterAddCommand = new DelegateCommand(ParameterAdd);
|
ParameterAddCommand = new DelegateCommand(ParameterAdd);
|
||||||
ParameterEditCommand = new DelegateCommand(ParameterEdit);
|
ParameterEditCommand = new DelegateCommand(ParameterEdit);
|
||||||
ParameterDeleteCommand = new DelegateCommand(ParameterDelete);
|
ParameterDeleteCommand = new DelegateCommand(ParameterDelete);
|
||||||
DeviceEditCommand = new DelegateCommand(DeviceEdit);
|
DeviceEditCommand = new DelegateCommand(DeviceEdit);
|
||||||
|
ReConnectCommand = new AsyncDelegateCommand(OnReConnect);
|
||||||
|
CloseCommand = new AsyncDelegateCommand(OnClose);
|
||||||
|
LoadedCommand = new DelegateCommand(OnLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 委托命令
|
#region 委托命令
|
||||||
|
private void OnLoad()
|
||||||
|
{
|
||||||
|
DeviceInfoVM = _systemConfig.DeviceList;
|
||||||
|
} private async Task OnReConnect()
|
||||||
|
{
|
||||||
|
await _deviceManager.ConnectSpecifiedDevice(SelectedDevice.DeviceName);
|
||||||
|
} private async Task OnClose()
|
||||||
|
{
|
||||||
|
await _deviceManager.CloseDeviceAsync(SelectedDevice.DeviceName);
|
||||||
|
}
|
||||||
private void DeviceEdit()
|
private void DeviceEdit()
|
||||||
{
|
{
|
||||||
if (!_globalInfo.IsAdmin) return;
|
if (!_globalInfo.IsAdmin) return;
|
||||||
@@ -98,14 +113,7 @@ namespace TestingModule.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var type = SelectedDevice.DeviceType.Split('.').Last();
|
var type = SelectedDevice.DeviceType.Split('.').Last();
|
||||||
if(type=="E36233A"|| type == "IT6724CReverse")
|
_dialogService.Show(type);
|
||||||
{
|
|
||||||
_dialogService.Show("Backfeed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_dialogService.Show(type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ParameterDelete()
|
private void ParameterDelete()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
|
xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
|
||||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||||
@@ -18,7 +19,11 @@
|
|||||||
<converters:ParameterCategoryToStringConverter x:Key="ParameterCategoryToStringConverter" />
|
<converters:ParameterCategoryToStringConverter x:Key="ParameterCategoryToStringConverter" />
|
||||||
<converters:ParameterValueToStringConverter x:Key="ParameterValueToStringConverter" />
|
<converters:ParameterValueToStringConverter x:Key="ParameterValueToStringConverter" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="Loaded">
|
||||||
|
<i:InvokeCommandAction Command="{Binding LoadedCommand}"/>
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>
|
||||||
<Grid>
|
<Grid>
|
||||||
<GroupBox Header="设备/参数">
|
<GroupBox Header="设备/参数">
|
||||||
<TabControl>
|
<TabControl>
|
||||||
@@ -123,7 +128,7 @@
|
|||||||
<MenuItem Header="编辑"
|
<MenuItem Header="编辑"
|
||||||
Command="{Binding DeviceEditCommand}" />
|
Command="{Binding DeviceEditCommand}" />
|
||||||
<MenuItem Header="重新连接"
|
<MenuItem Header="重新连接"
|
||||||
Command="{Binding ReconnnectCommand}" />
|
Command="{Binding ReConnectCommand}" />
|
||||||
<MenuItem Header="关闭"
|
<MenuItem Header="关闭"
|
||||||
Command="{Binding CloseCommand}" />
|
Command="{Binding CloseCommand}" />
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace UIShare.GlobalVariable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeviceManager
|
public class DeviceManager
|
||||||
{
|
{
|
||||||
|
private object _lockObj = new object();
|
||||||
public SystemConfig _systemConfig { get; set; }
|
public SystemConfig _systemConfig { get; set; }
|
||||||
|
|
||||||
/// <summary>按 DeviceName 索引的设备字典,便于业务层按名取实例。</summary>
|
/// <summary>按 DeviceName 索引的设备字典,便于业务层按名取实例。</summary>
|
||||||
@@ -115,7 +116,86 @@ namespace UIShare.GlobalVariable
|
|||||||
await ConnectInternalAsync(info, device, ct);
|
await ConnectInternalAsync(info, device, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步关闭指定设备,释放底层连接并更新 UI 状态
|
||||||
|
/// </summary>
|
||||||
|
public async Task CloseDeviceAsync(string deviceName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(deviceName)) return;
|
||||||
|
|
||||||
|
IBaseInterface? device;
|
||||||
|
DeviceInfoVM? info;
|
||||||
|
|
||||||
|
lock (_lockObj)
|
||||||
|
{
|
||||||
|
if (!DeviceMap.TryGetValue(deviceName, out device)) return;
|
||||||
|
|
||||||
|
info = _systemConfig?.DeviceList?
|
||||||
|
.FirstOrDefault(d => d != null && string.Equals(d.DeviceName, deviceName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
await CloseInternalAsync(info, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步关闭所有设备
|
||||||
|
/// </summary>
|
||||||
|
public async Task CloseAllDevicesAsync()
|
||||||
|
{
|
||||||
|
List<Task> tasks = new List<Task>();
|
||||||
|
|
||||||
|
lock (_lockObj)
|
||||||
|
{
|
||||||
|
if (DeviceMap.Count == 0) return;
|
||||||
|
|
||||||
|
foreach (var kvp in DeviceMap)
|
||||||
|
{
|
||||||
|
string deviceName = kvp.Key;
|
||||||
|
var device = kvp.Value;
|
||||||
|
var info = _systemConfig?.DeviceList?
|
||||||
|
.FirstOrDefault(d => d != null && string.Equals(d.DeviceName, deviceName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
tasks.Add(CloseInternalAsync(info, device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.WhenAll(tasks);
|
||||||
|
LoggerHelper.Info("所有设备已执行关闭操作。");
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 辅助方法
|
||||||
|
private async Task CloseInternalAsync(DeviceInfoVM? info, IBaseInterface device)
|
||||||
|
{
|
||||||
|
string name = info?.DeviceName ?? device.GetType().Name;
|
||||||
|
string conn = info?.ConnectionType ?? "?";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 如果设备本身已经是断开状态,直接更新 UI 并返回
|
||||||
|
if (!device.IsConnected)
|
||||||
|
{
|
||||||
|
if (info != null) info.IsConnected = false;
|
||||||
|
LoggerHelper.Info($"设备 [{name}] 本就处于断开状态。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await Task.Run(() => device.Close());
|
||||||
|
|
||||||
|
LoggerHelper.Info($"设备 [{name}/{conn}] 已成功关闭连接。");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var inner = ex.InnerException?.Message ?? ex.Message;
|
||||||
|
LoggerHelper.Error($"设备 [{name}/{conn}] 关闭连接时出现异常: {inner}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// 无论关闭时是否抛出异常,均强制同步 UI 状态为未连接
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
info.IsConnected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private async Task ConnectInternalAsync(DeviceInfoVM? info, IBaseInterface device, CancellationToken ct)
|
private async Task ConnectInternalAsync(DeviceInfoVM? info, IBaseInterface device, CancellationToken ct)
|
||||||
{
|
{
|
||||||
string name = info?.DeviceName ?? device.GetType().Name;
|
string name = info?.DeviceName ?? device.GetType().Name;
|
||||||
@@ -176,7 +256,6 @@ namespace UIShare.GlobalVariable
|
|||||||
}
|
}
|
||||||
return await sp.ConnectAsync(ct);
|
return await sp.ConnectAsync(ct);
|
||||||
}
|
}
|
||||||
#region 辅助方法
|
|
||||||
private static IReadOnlyDictionary<string, Type> BuildDeviceTypeMap()
|
private static IReadOnlyDictionary<string, Type> BuildDeviceTypeMap()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user