$ErrorActionPreference = "Stop"
# ============================================================
# 通用模板函数
# ============================================================
function Write-ViewModel {
param(
[string]$ProjectPath, # e.g. "c:\Users\kk\Desktop\BOB"
[string]$ClassName, # e.g. "E36233A"
[string]$DeviceType, # e.g. "可编程直流电源"
[string]$DeviceNamespace, # e.g. "DeviceCommand.Device"
[string]$Properties, # C# property block
[string]$Commands, # ICommand declarations
[string]$CommandInits, # Command initialization in constructor
[string]$ExtraUsings = ""
)
$dir = Join-Path $ProjectPath "DeviceEditModule\ViewModels"
if (!(Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
$content = @"
using $DeviceNamespace;
using Prism.Commands;
using Prism.Ioc;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using UIShare.GlobalVariable;
using UIShare.ViewModelBase;
$ExtraUsings
namespace DeviceEditModule.ViewModels
{
///
/// $ClassName $DeviceType 控制面板 ViewModel
///
public class ${ClassName}ViewModel : NavigateViewModelBase, IDisposable
{
#region 私有字段
private readonly DeviceManager _deviceManager;
private ${ClassName}? _device;
private CancellationTokenSource? _cts;
#endregion
#region 设备信息属性
private string _deviceName = "$ClassName";
public string DeviceName
{
get => _deviceName;
set => SetProperty(ref _deviceName, value);
}
private bool _isConnected;
public bool IsConnected
{
get => _isConnected;
set => SetProperty(ref _isConnected, value);
}
private bool _isBusy;
/// 正在执行设备命令时为 true,用于 UI 忙碌状态指示。
public bool IsBusy
{
get => _isBusy;
set => SetProperty(ref _isBusy, value);
}
#endregion
$Properties
private string _responseLog = string.Empty;
/// 命令响应日志(最新消息在顶部)。
public string ResponseLog
{
get => _responseLog;
set => SetProperty(ref _responseLog, value);
}
#endregion
#region 命令
$Commands
#endregion
public ${ClassName}ViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
_deviceManager = containerProvider.Resolve();
$CommandInits
Initialize();
}
#region 初始化 / Navigation
public void Initialize(string? deviceName = null)
{
${ClassName}? found = null;
string? foundName = null;
if (deviceName != null &&
_deviceManager.DeviceMap.TryGetValue(deviceName, out var d) &&
d is ${ClassName} e)
{
found = e;
foundName = deviceName;
}
else
{
foreach (var kv in _deviceManager.DeviceMap)
{
if (kv.Value is ${ClassName} it)
{
found = it;
foundName = kv.Key;
break;
}
}
}
_device = found;
DeviceName = foundName ?? "$ClassName (未找到)";
IsConnected = _device?.IsConnected ?? false;
AppendLog(found != null
? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "已连接" : "未连接")}"
: "未在 DeviceManager 中找到 $ClassName 设备,请先初始化设备配置。");
}
public override void OnNavigatedTo(NavigationContext context)
{
var name = context.Parameters.GetValue("DeviceName");
Initialize(name);
}
#endregion
#region 辅助
private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token;
private async Task Exec(Func action)
{
if (_device == null)
{
AppendLog("错误:未关联到设备实例,请检查设备配置。");
return;
}
if (IsBusy) return;
IsBusy = true;
try
{
await action();
IsConnected = _device.IsConnected;
}
catch (OperationCanceledException)
{
AppendLog("命令超时或已取消。");
}
catch (Exception ex)
{
AppendLog($"错误:{ex.Message}");
}
finally
{
IsBusy = false;
}
}
private void AppendLog(string message)
{
var line = $"[{DateTime.Now:HH:mm:ss}] {message}";
ResponseLog = ResponseLog.Length > 4000
? line + "\n" + ResponseLog[..3000]
: line + "\n" + ResponseLog;
}
#endregion
public void Dispose()
{
_cts?.Cancel();
_cts?.Dispose();
}
}
}
"@
$file = Join-Path $dir "${ClassName}ViewModel.cs"
[System.IO.File]::WriteAllText($file, $content, [System.Text.Encoding]::UTF8)
Write-Host " Created: $file"
}
function Write-ViewXaml {
param(
[string]$ProjectPath,
[string]$ClassName,
[string]$DeviceTitle, # e.g. "E36233A 可编程直流电源"
[string]$Icon, # e.g. "Flash"
[string]$LeftGroups, # GroupBox XAML blocks for left column
[string]$RightGroups # GroupBox XAML blocks for right column
)
$dir = Join-Path $ProjectPath "DeviceEditModule\Views"
if (!(Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
$content = @"
$LeftGroups
$RightGroups
"@
$file = Join-Path $dir "${ClassName}View.xaml"
[System.IO.File]::WriteAllText($file, $content, [System.Text.Encoding]::UTF8)
Write-Host " Created: $file"
}
function Write-ViewXamlCs {
param(
[string]$ProjectPath,
[string]$ClassName
)
$dir = Join-Path $ProjectPath "DeviceEditModule\Views"
$content = @"
using System.Windows.Controls;
namespace DeviceEditModule.Views
{
///
/// ${ClassName}View.xaml 的交互逻辑
///
public partial class ${ClassName}View : UserControl
{
public ${ClassName}View()
{
InitializeComponent();
}
}
}
"@
$file = Join-Path $dir "${ClassName}View.xaml.cs"
[System.IO.File]::WriteAllText($file, $content, [System.Text.Encoding]::UTF8)
Write-Host " Created: $file"
}
# ============================================================
# XAML 通用片段
# ============================================================
$XamlLogGroup = @"
"@
function Xaml-OutputControl($onCmd, $offCmd, $onLabel="开启输出", $offLabel="关闭输出") {
return @"
"@
}
function Xaml-ParamInput($header, $label, $binding, $cmd) {
return @"
"@
}
function Xaml-Measure($label, $binding, $unit) {
return @"
"@
}
function Xaml-MeasureGroup($header, $measures, $refreshCmd=$null) {
$refreshBtn = ""
if ($refreshCmd) {
$refreshBtn = @"
"@
}
return @"
$measures
$refreshBtn
"@
}
# ============================================================
# BOB 设备
# ============================================================
$BOB = "c:\Users\kk\Desktop\BOB"
Write-Host "=== Generating BOB device edit views ==="
# --- 1. E36233A ---
Write-Host "`n--- E36233A ---"
Write-ViewModel -ProjectPath $BOB -ClassName "E36233A" -DeviceType "可编程直流电源" -DeviceNamespace "DeviceCommand.Device" `
-Properties @"
#region 输入参数属性
private double _voltage = 0.0;
public double Voltage { get => _voltage; set => SetProperty(ref _voltage, value); }
private double _current = 0.0;
public double Current { get => _current; set => SetProperty(ref _current, value); }
private double _ocpValue = 0.0;
public double OcpValue { get => _ocpValue; set => SetProperty(ref _ocpValue, value); }
private double _ovpValue = 0.0;
public double OvpValue { get => _ovpValue; set => SetProperty(ref _ovpValue, value); }
private int _channel = 1;
public int Channel { get => _channel; set => SetProperty(ref _channel, value); }
#endregion
#region 测量结果属性
private double _measuredVoltage;
public double MeasuredVoltage { get => _measuredVoltage; set => SetProperty(ref _measuredVoltage, value); }
private double _measuredCurrent;
public double MeasuredCurrent { get => _measuredCurrent; set => SetProperty(ref _measuredCurrent, value); }
"@ `
-Commands @"
public ICommand QueryIdentityCommand { get; }
public ICommand OutputOnCommand { get; }
public ICommand OutputOffCommand { get; }
public ICommand SetRemoteCommand { get; }
public ICommand SetVoltageCommand { get; }
public ICommand SetCurrentCommand { get; }
public ICommand SetOcpCommand { get; }
public ICommand SetOvpCommand { get; }
public ICommand SetChannelCommand { get; }
public ICommand QueryMeasureCommand { get; }
public ICommand ClearProtectionCommand { get; }
"@ `
-CommandInits @"
QueryIdentityCommand = new DelegateCommand(async () => await Exec(async () => AppendLog("IDN: " + await _device!.查询设备信息(Ct()))));
OutputOnCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电源输出(true, Ct()); AppendLog("输出已开启"); }));
OutputOffCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电源输出(false, Ct()); AppendLog("输出已关闭"); }));
SetRemoteCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置为远程模式(Ct()); AppendLog("已切换到远程控制模式"); }));
SetVoltageCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电压(Voltage, Ct()); AppendLog($"电压已设为 {Voltage} V"); }));
SetCurrentCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电流(Current, Ct()); AppendLog($"电流已设为 {Current} A"); }));
SetOcpCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电流保护OCP电流(OcpValue, Ct()); AppendLog($"OCP已设为 {OcpValue} A"); }));
SetOvpCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电压保护OVP电压(OvpValue, Ct()); AppendLog($"OVP已设为 {OvpValue} V"); }));
SetChannelCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置通道(Channel, Ct()); AppendLog($"通道已设为 {Channel}"); }));
ClearProtectionCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.清除电流保护(Ct()); await _device!.清除电压保护(Ct()); AppendLog("保护已清除"); }));
QueryMeasureCommand = new DelegateCommand(async () => await Exec(async () =>
{
MeasuredVoltage = await _device!.查询电压(Ct());
MeasuredCurrent = await _device!.查询电流(Ct());
AppendLog($"测量 -> 电压:{MeasuredVoltage}V 电流:{MeasuredCurrent}A");
}));
"@
Write-ViewXaml -ProjectPath $BOB -ClassName "E36233A" -DeviceTitle "E36233A 可编程直流电源" -Icon "Flash" `
-LeftGroups @"
$(Xaml-OutputControl "OutputOnCommand" "OutputOffCommand")
$(Xaml-ParamInput "电压设置" "电压 (V)" "Voltage" "SetVoltageCommand")
$(Xaml-ParamInput "电流设置" "电流 (A)" "Current" "SetCurrentCommand")
$(Xaml-ParamInput "OCP设置" "OCP (A)" "OcpValue" "SetOcpCommand")
$(Xaml-ParamInput "OVP设置" "OVP (V)" "OvpValue" "SetOvpCommand")
"@ `
-RightGroups @"
$(Xaml-MeasureGroup "实时测量" "$(Xaml-Measure '实际电压' 'MeasuredVoltage' 'V')
$(Xaml-Measure '实际电流' 'MeasuredCurrent' 'A')" "QueryMeasureCommand")
$XamlLogGroup
"@
Write-ViewXamlCs -ProjectPath $BOB -ClassName "E36233A"
# --- 2. EAEL9080 ---
Write-Host "`n--- EAEL9080 ---"
Write-ViewModel -ProjectPath $BOB -ClassName "EAEL9080" -DeviceType "双向可编程直流电源" -DeviceNamespace "DeviceCommand.Device" `
-Properties @"
#region 输入参数属性
private double _voltage = 0.0;
public double Voltage { get => _voltage; set => SetProperty(ref _voltage, value); }
private double _current = 0.0;
public double Current { get => _current; set => SetProperty(ref _current, value); }
private double _power = 0.0;
public double Power { get => _power; set => SetProperty(ref _power, value); }
private double _ovpValue = 0.0;
public double OvpValue { get => _ovpValue; set => SetProperty(ref _ovpValue, value); }
private double _ocpValue = 0.0;
public double OcpValue { get => _ocpValue; set => SetProperty(ref _ocpValue, value); }
#endregion
#region 测量结果属性
private string _measuredVoltage = "";
public string MeasuredVoltage { get => _measuredVoltage; set => SetProperty(ref _measuredVoltage, value); }
private string _measuredCurrent = "";
public string MeasuredCurrent { get => _measuredCurrent; set => SetProperty(ref _measuredCurrent, value); }
private string _measuredPower = "";
public string MeasuredPower { get => _measuredPower; set => SetProperty(ref _measuredPower, value); }
#endregion
"@ `
-Commands @"
public ICommand QueryIdentityCommand { get; }
public ICommand ResetDeviceCommand { get; }
public ICommand OutputOnCommand { get; }
public ICommand OutputOffCommand { get; }
public ICommand InputOnCommand { get; }
public ICommand InputOffCommand { get; }
public ICommand SetVoltageCommand { get; }
public ICommand SetCurrentCommand { get; }
public ICommand SetPowerCommand { get; }
public ICommand SetOvpCommand { get; }
public ICommand SetOcpCommand { get; }
public ICommand QueryMeasureCommand { get; }
public ICommand RemoteOnCommand { get; }
public ICommand RemoteOffCommand { get; }
"@ `
-CommandInits @"
QueryIdentityCommand = new DelegateCommand(async () => await Exec(async () => AppendLog("IDN: " + await _device!.查询设备标识(Ct()))));
ResetDeviceCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.重置设备(Ct()); AppendLog("设备已重置"); }));
OutputOnCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置DC输出(true, Ct()); AppendLog("DC输出已开启"); }));
OutputOffCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置DC输出(false, Ct()); AppendLog("DC输出已关闭"); }));
InputOnCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置DC输入(true, Ct()); AppendLog("DC输入已开启"); }));
InputOffCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置DC输入(false, Ct()); AppendLog("DC输入已关闭"); }));
SetVoltageCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电压(Voltage, Ct()); AppendLog($"电压已设为 {Voltage} V"); }));
SetCurrentCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电流(Current, Ct()); AppendLog($"电流已设为 {Current} A"); }));
SetPowerCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置功率(Power, Ct()); AppendLog($"功率已设为 {Power} W"); }));
SetOvpCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置过压保护(OvpValue, Ct()); AppendLog($"OVP已设为 {OvpValue} V"); }));
SetOcpCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.设置过流保护(OcpValue, Ct()); AppendLog($"OCP已设为 {OcpValue} A"); }));
RemoteOnCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.激活远程控制(true, Ct()); AppendLog("远程控制已激活"); }));
RemoteOffCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.激活远程控制(false, Ct()); AppendLog("远程控制已释放"); }));
QueryMeasureCommand = new DelegateCommand(async () => await Exec(async () =>
{
MeasuredVoltage = await _device!.查询实际电压(Ct());
MeasuredCurrent = await _device!.查询实际电流(Ct());
MeasuredPower = await _device!.查询实际功率(Ct());
AppendLog($"测量 -> 电压:{MeasuredVoltage} 电流:{MeasuredCurrent} 功率:{MeasuredPower}");
}));
"@
Write-ViewXaml -ProjectPath $BOB -ClassName "EAEL9080" -DeviceTitle "EA EL9080 双向可编程直流电源" -Icon "Flash" `
-LeftGroups @"
$(Xaml-ParamInput "电压设置" "电压 (V)" "Voltage" "SetVoltageCommand")
$(Xaml-ParamInput "电流设置" "电流 (A)" "Current" "SetCurrentCommand")
$(Xaml-ParamInput "功率设置" "功率 (W)" "Power" "SetPowerCommand")
$(Xaml-ParamInput "OVP设置" "OVP (V)" "OvpValue" "SetOvpCommand")
$(Xaml-ParamInput "OCP设置" "OCP (A)" "OcpValue" "SetOcpCommand")
"@ `
-RightGroups @"
$(Xaml-MeasureGroup "实时测量" "$(Xaml-Measure '实际电压' 'MeasuredVoltage' 'V')
$(Xaml-Measure '实际电流' 'MeasuredCurrent' 'A')
$(Xaml-Measure '实际功率' 'MeasuredPower' 'W')" "QueryMeasureCommand")
$XamlLogGroup
"@
Write-ViewXamlCs -ProjectPath $BOB -ClassName "EAEL9080"
Write-Host "BOB part 1 done (E36233A, EAEL9080)"