将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Prism.Commands;
|
||||
using Prism.Mvvm;
|
||||
using XP.Hardware.PLC.Models;
|
||||
|
||||
namespace XP.Hardware.PLC.Sentry.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// 单行信号 ViewModel,封装 SignalEntry 并添加运行时状态 | Single signal row ViewModel wrapping SignalEntry with runtime state
|
||||
/// </summary>
|
||||
public class SignalRowViewModel : BindableBase
|
||||
{
|
||||
private readonly SignalEntry _signal;
|
||||
private string _currentValue = "--";
|
||||
private bool _hasReadError;
|
||||
private object _writeValue;
|
||||
private string _validationError;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数 | Constructor
|
||||
/// </summary>
|
||||
/// <param name="signal">信号定义条目 | Signal definition entry</param>
|
||||
/// <param name="applyAction">队列写入回调 | Queue write callback</param>
|
||||
/// <param name="directWriteAction">直接写入回调 | Direct write callback</param>
|
||||
/// <param name="canExecuteWrite">写入命令是否可用判断 | Write command can-execute predicate</param>
|
||||
public SignalRowViewModel(
|
||||
SignalEntry signal,
|
||||
Action<SignalRowViewModel> applyAction,
|
||||
Action<SignalRowViewModel> directWriteAction,
|
||||
Func<bool> canExecuteWrite)
|
||||
{
|
||||
_signal = signal ?? throw new ArgumentNullException(nameof(signal));
|
||||
|
||||
ApplyCommand = new DelegateCommand(
|
||||
() => applyAction?.Invoke(this),
|
||||
() => canExecuteWrite?.Invoke() ?? false);
|
||||
|
||||
DirectWriteCommand = new DelegateCommand(
|
||||
() => directWriteAction?.Invoke(this),
|
||||
() => canExecuteWrite?.Invoke() ?? false);
|
||||
}
|
||||
|
||||
// === 信号定义信息(只读)| Signal definition info (read-only) ===
|
||||
|
||||
/// <summary>
|
||||
/// 信号名称 | Signal name
|
||||
/// </summary>
|
||||
public string Name => _signal.Name;
|
||||
|
||||
/// <summary>
|
||||
/// 数据类型 | Data type
|
||||
/// </summary>
|
||||
public string Type => _signal.Type;
|
||||
|
||||
/// <summary>
|
||||
/// 起始地址 | Start address
|
||||
/// </summary>
|
||||
public int StartAddr => _signal.StartAddr;
|
||||
|
||||
/// <summary>
|
||||
/// 长度/索引 | Length/Index
|
||||
/// </summary>
|
||||
public string IndexOrLength => _signal.IndexOrLength;
|
||||
|
||||
/// <summary>
|
||||
/// 备注 | Remark
|
||||
/// </summary>
|
||||
public string Remark => _signal.Remark;
|
||||
|
||||
/// <summary>
|
||||
/// DB 块号 | DB block number
|
||||
/// </summary>
|
||||
public int DBNumber => _signal.DBNumber;
|
||||
|
||||
/// <summary>
|
||||
/// 原始信号定义条目 | Original signal definition entry
|
||||
/// </summary>
|
||||
public SignalEntry Signal => _signal;
|
||||
|
||||
/// <summary>
|
||||
/// 格式化的地址显示 | Formatted address display
|
||||
/// bool 类型显示位地址(DB{n}.{addr}.{bit}),其他类型显示字节地址(DB{n}.{addr})
|
||||
/// </summary>
|
||||
public string AddressDisplay => Type?.ToLowerInvariant() == "bool"
|
||||
? $"DB{DBNumber}.{StartAddr}.{IndexOrLength}"
|
||||
: $"DB{DBNumber}.{StartAddr}";
|
||||
|
||||
// === 运行时状态 | Runtime state ===
|
||||
|
||||
/// <summary>
|
||||
/// 当前读取值 | Current read value
|
||||
/// </summary>
|
||||
public string CurrentValue
|
||||
{
|
||||
get => _currentValue;
|
||||
set => SetProperty(ref _currentValue, value ?? "--");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在读取错误 | Whether read error exists
|
||||
/// </summary>
|
||||
public bool HasReadError
|
||||
{
|
||||
get => _hasReadError;
|
||||
set => SetProperty(ref _hasReadError, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入值 | Write value
|
||||
/// </summary>
|
||||
public object WriteValue
|
||||
{
|
||||
get => _writeValue;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _writeValue, value))
|
||||
{
|
||||
// 写入值变更时清除校验错误 | Clear validation error when write value changes
|
||||
ValidationError = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验错误信息 | Validation error message
|
||||
/// </summary>
|
||||
public string ValidationError
|
||||
{
|
||||
get => _validationError;
|
||||
set => SetProperty(ref _validationError, value);
|
||||
}
|
||||
|
||||
// === 命令 | Commands ===
|
||||
|
||||
/// <summary>
|
||||
/// 队列写入命令 | Queue write command
|
||||
/// </summary>
|
||||
public DelegateCommand ApplyCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 直接写入+回读校验命令 | Direct write with verify command
|
||||
/// </summary>
|
||||
public DelegateCommand DirectWriteCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 刷新写入命令可用状态 | Refresh write command can-execute state
|
||||
/// </summary>
|
||||
public void RefreshCommandState()
|
||||
{
|
||||
ApplyCommand.RaiseCanExecuteChanged();
|
||||
DirectWriteCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验写入值是否符合信号数据类型要求 | Validate write value against signal data type
|
||||
/// </summary>
|
||||
/// <returns>校验错误信息,null 表示通过 | Validation error message, null means passed</returns>
|
||||
public string ValidateWriteValue()
|
||||
{
|
||||
if (WriteValue == null)
|
||||
return "写入值不能为空 | Write value cannot be empty";
|
||||
|
||||
var strValue = WriteValue.ToString();
|
||||
if (string.IsNullOrWhiteSpace(strValue))
|
||||
return "写入值不能为空 | Write value cannot be empty";
|
||||
|
||||
switch (Type?.ToLowerInvariant())
|
||||
{
|
||||
case "bool":
|
||||
if (!bool.TryParse(strValue, out _))
|
||||
return "布尔值仅接受 True/False | Bool accepts only True/False";
|
||||
break;
|
||||
case "byte":
|
||||
if (!byte.TryParse(strValue, out _))
|
||||
return "字节值超出范围 (0-255) | Byte value out of range (0-255)";
|
||||
break;
|
||||
case "short":
|
||||
if (!short.TryParse(strValue, out _))
|
||||
return "短整型值超出范围 | Short value out of range";
|
||||
break;
|
||||
case "int":
|
||||
if (!int.TryParse(strValue, out _))
|
||||
return "整型值超出范围 | Int value out of range";
|
||||
break;
|
||||
case "single":
|
||||
if (!float.TryParse(strValue, out _))
|
||||
return "浮点数格式错误 | Float format error";
|
||||
break;
|
||||
case "double":
|
||||
if (!double.TryParse(strValue, out _))
|
||||
return "双精度浮点数格式错误 | Double format error";
|
||||
break;
|
||||
case "string":
|
||||
// 字符串接受任意非空值 | String accepts any non-empty value
|
||||
break;
|
||||
default:
|
||||
return $"不支持的类型: {Type} | Unsupported type: {Type}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user