添加项目文件。

This commit is contained in:
“hsc”
2026-07-29 13:12:27 +08:00
parent d6da766e2d
commit 8cf45d36b9
297 changed files with 35814 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
namespace UIShare.UIViewModel
{
/// <summary>
/// CAN 通道枚举(对应 ZLGCANFD 通道选择)
/// </summary>
public enum APP_CHANNEL
{
CH0 = 0,
CH1 = 1,
CH2 = 2,
CH3 = 3
}
/// <summary>
/// DBC 自动加载配置项
/// </summary>
public class AutoDBCLoadItem : BindableBase
{
private int _dbcChannel;
public int DBCChannel
{
get => _dbcChannel;
set => SetProperty(ref _dbcChannel, value);
}
private string _dbcFilePath;
public string DBCFilePath
{
get => _dbcFilePath;
set => SetProperty(ref _dbcFilePath, value);
}
}
}

View File

@@ -0,0 +1,76 @@
using Prism.Mvvm;
namespace UIShare.UIViewModel
{
/// <summary>
/// CAN 连接配置(对应 ZLGCANFD 构造函数 + 初始化并启动通道 参数)。
/// </summary>
public class CANConfigVM : BindableBase
{
// ===== ZLGCANFD 构造函数参数 =====
private uint _deviceType = 43;
/// <summary>设备类型号43 = USBCANFD-400U</summary>
public uint DeviceType
{
get => _deviceType;
set => SetProperty(ref _deviceType, value);
}
private uint _deviceIndex = 0;
/// <summary>设备索引</summary>
public uint DeviceIndex
{
get => _deviceIndex;
set => SetProperty(ref _deviceIndex, value);
}
private string _abitBaud = "500000";
/// <summary>仲裁域波特率</summary>
public string ABitBaud
{
get => _abitBaud;
set => SetProperty(ref _abitBaud, value);
}
private string _dbitBaud = "2000000";
/// <summary>数据域波特率</summary>
public string DBitBaud
{
get => _dbitBaud;
set => SetProperty(ref _dbitBaud, value);
}
private bool _enableTerminalResistance = true;
/// <summary>是否开启终端电阻</summary>
public bool EnableTerminalResistance
{
get => _enableTerminalResistance;
set => SetProperty(ref _enableTerminalResistance, value);
}
public CANConfigVM() { }
/// <summary>拷贝构造,用于对话框编辑副本。</summary>
public CANConfigVM(CANConfigVM? src)
{
if (src == null) return;
DeviceType = src.DeviceType;
DeviceIndex = src.DeviceIndex;
ABitBaud = src.ABitBaud;
DBitBaud = src.DBitBaud;
EnableTerminalResistance = src.EnableTerminalResistance;
}
/// <summary>把字段拷回目标对象(保存时用)。</summary>
public void CopyTo(CANConfigVM? dst)
{
if (dst == null) return;
dst.DeviceType = DeviceType;
dst.DeviceIndex = DeviceIndex;
dst.ABitBaud = ABitBaud;
dst.DBitBaud = DBitBaud;
dst.EnableTerminalResistance = EnableTerminalResistance;
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace UIShare.UIViewModel
{
public class CANSignalConfig
{
public int Channel { get; set; }
public int MessageID { get; set; }
public string MessageName { get; set; }
public string SignalName { get; set; }
public int CollectionInterval { get; set; }
public Guid CollectionID { get; set; }
public string MethodName {get;set;}
}
}

View File

@@ -0,0 +1,42 @@
namespace UIShare.UIViewModel
{
public class CanMessageShowVM : BindableBase
{
// 字段声明
private byte _通道;
private int _报文ID;
private double _时间戳;
private byte _长度;
// 通道属性
public byte
{
get { return _通道; }
set { SetProperty(ref _通道, value); }
}
// 报文ID属性
public int ID
{
get { return _报文ID; }
set { SetProperty(ref _报文ID, value); }
}
// 时间戳属性
public double
{
get { return _时间戳; }
set { SetProperty(ref _时间戳, value); }
}
// 长度属性
public byte
{
get { return _长度; }
set { SetProperty(ref _长度, value); }
}
}
}

View File

@@ -0,0 +1,22 @@
using Prism.Mvvm;
namespace UIShare.UIViewModel
{
public class CustomPanelItemVM : BindableBase
{
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private string _pointY;
public string PointY
{
get => _pointY;
set => SetProperty(ref _pointY, value);
}
}
}

View File

@@ -0,0 +1,80 @@
using Newtonsoft.Json;
namespace UIShare.UIViewModel
{
public class DeviceInfoVM : BindableBase
{
private string _deviceName;
public string DeviceName
{
get => _deviceName;
set => SetProperty(ref _deviceName, value);
}
private string _deviceType;
public string DeviceType
{
get => _deviceType;
set => SetProperty(ref _deviceType, value);
}
private string _remark;
public string Remark
{
get => _remark;
set => SetProperty(ref _remark, value);
}
private bool _isEnabled;
public bool IsEnabled
{
get => _isEnabled;
set => SetProperty(ref _isEnabled, value);
}
private bool _isConnected=false;
[JsonIgnore]
public bool IsConnected
{
get => _isConnected;
set => SetProperty(ref _isConnected, value);
}
/// <summary>
/// 连接方式:"None" / "TCP" / "Serial"。
/// 用于决定 SettingView 上"配置..."按钮打开哪一个对话框。
/// </summary>
private string _connectionType ;
public string ConnectionType
{
get => _connectionType;
set => SetProperty(ref _connectionType, value);
}
/// <summary>TCP 连接参数(首次访问时自动初始化,便于 XAML 直接绑定)。</summary>
private TcpConfigVM _tcpConfig = new();
public TcpConfigVM TcpConfig
{
get => _tcpConfig;
set => SetProperty(ref _tcpConfig, value);
}
/// <summary>串口连接参数(首次访问时自动初始化,便于 XAML 直接绑定)。</summary>
private SerialPortConfigVM _serialPortConfig = new();
public SerialPortConfigVM SerialPortConfig
{
get => _serialPortConfig;
set => SetProperty(ref _serialPortConfig, value);
}
/// <summary>CAN 连接参数(对应 ZLGCANFD 构造 + 通道初始化参数)。</summary>
private CANConfigVM _canConfig = new();
public CANConfigVM CANConfig
{
get => _canConfig;
set => SetProperty(ref _canConfig, value);
}
}
}

View File

@@ -0,0 +1,25 @@
namespace UIShare.UIViewModel
{
/// <summary>
/// 弹窗 Tab 信息载体(事件负载,轻量 POCO
/// 其他模块发布 <c>AddDialogTabEvent</c> 时填充此对象,
/// DialogMangerViewModel 接收后创建对应的 Tab 项。
/// </summary>
public class DialogTabInfo
{
/// <summary>Tab 标题(显示在标签页上)。</summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 设备硬件指纹(如 "Tcp:192.168.1.100:502"),用于去重判断,
/// 防止同一物理设备被重复打开多个 Tab。
/// </summary>
public string Fingerprint { get; set; } = string.Empty;
/// <summary>
/// Tab 内容:传入一个已实例化的 <see cref="System.Windows.FrameworkElement"/>(通常是 UserControl
/// 由 ContentControl 直接承载展示。
/// </summary>
public object? Content { get; set; }
}
}

View File

@@ -0,0 +1,68 @@
using Prism.Commands;
using Prism.Mvvm;
using System;
namespace DeviceEditModule.ViewModels
{
/// <summary>
/// 弹窗管理器中单个 Tab 项的 ViewModel。
/// 由 <see cref="DialogMangerViewModel"/> 在收到 AddDialogTabEvent 时创建,
/// 通过构造函数注入选中/关闭的回调,保持与父 ViewModel 的低耦合。
/// </summary>
public class DialogTabItemVM : BindableBase
{
#region
private string _title = string.Empty;
/// <summary>Tab 标签页上显示的标题。</summary>
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
private string _fingerprint = string.Empty;
/// <summary>设备硬件指纹,用于去重字典的 Key。</summary>
public string Fingerprint
{
get => _fingerprint;
set => SetProperty(ref _fingerprint, value);
}
private object? _content;
/// <summary>Tab 内容区域(通常为 UserControl 实例)。</summary>
public object? Content
{
get => _content;
set => SetProperty(ref _content, value);
}
private bool _isSelected;
/// <summary>是否为当前激活 Tab用于切换选中态样式。</summary>
public bool IsSelected
{
get => _isSelected;
set => SetProperty(ref _isSelected, value);
}
#endregion
#region
/// <summary>点击 Tab 标题激活该 Tab。</summary>
public DelegateCommand SelectCommand { get; }
/// <summary>点击 Tab 上的 × 关闭并移除该 Tab。</summary>
public DelegateCommand CloseCommand { get; }
#endregion
/// <param name="onSelect">父 VM 提供的激活回调。</param>
/// <param name="onClose">父 VM 提供的关闭回调。</param>
public DialogTabItemVM(Action<DialogTabItemVM> onSelect, Action<DialogTabItemVM> onClose)
{
SelectCommand = new DelegateCommand(() => onSelect(this));
CloseCommand = new DelegateCommand(() => onClose(this));
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Prism.Mvvm; // 确保引入了 Prism 命名空间
namespace UIShare.UIViewModel
{
public class InstructionNodeVM : BindableBase
{
private string _name = string.Empty;
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private ObservableCollection<InstructionNodeVM> _children = new();
public ObservableCollection<InstructionNodeVM> Children
{
get => _children;
set => SetProperty(ref _children, value);
}
private object? _tag;
public object? Tag
{
get => _tag;
set => SetProperty(ref _tag, value);
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UIShare.UIViewModel
{
public class MethodVM
{
#region
public MethodVM()
{
}
public MethodVM(MethodVM source)
{
if (source == null) return;
Name = source.Name;
FullName = source.FullName;
// 深拷贝参数
Parameters = new ObservableCollection<ParameterVM>(
source.Parameters.Select(p => new ParameterVM(p)));
}
#endregion
public string? Name { get; set; }
public string? FullName { get; set; }
public ObservableCollection<ParameterVM> Parameters { get; set; } = [];
}
}

View File

@@ -0,0 +1,94 @@
using OxyPlot.Series;
using OxyPlot;
using System;
using System.Collections.Concurrent;
using Prism.Mvvm;
using NCalc;
namespace UIShare.UIViewModel
{
/// <summary>
/// 监测通道:一个设备方法对应一个通道。
/// 数据记录DataPoints与图表显示Series完全分离
/// - IsMonitored=true 时始终记录 DataPoints
/// - IsDisplayed=true 时才创建 LineSeries 并绘制
/// </summary>
public class MonitorChannelVM : BindableBase
{
// ===== 标识 =====
public string DeviceName { get; init; } = string.Empty;
/// <summary>硬件指纹(物理设备唯一标识,用于匹配广播事件)</summary>
public string Fingerprint { get; init; } = string.Empty;
public string MethodName { get; init; } = string.Empty;
public string DisplayName { get; init; } = string.Empty;
// ===== 状态 =====
private bool _isMonitored = true;
/// <summary>是否在记录数据点(添加后始终为 true</summary>
public bool IsMonitored
{
get => _isMonitored;
set => SetProperty(ref _isMonitored, value);
}
private bool _isDisplayed = true;
/// <summary>是否在 OxyPlot 上显示</summary>
public bool IsDisplayed
{
get => _isDisplayed;
set => SetProperty(ref _isDisplayed, value);
}
// ===== 数学变换 =====
private string? _mathExpression;
/// <summary>可选数学变换表达式,如 "x*0.001"。为空则 DisplayValue=RawValue</summary>
public string? MathExpression
{
get => _mathExpression;
set => SetProperty(ref _mathExpression, value);
}
// ===== 颜色 =====
public OxyColor Color { get; set; } = OxyColors.SteelBlue;
// ===== 数据存储 =====
/// <summary>所有采样数据点(线程安全),与 OxyPlot 无关</summary>
public ConcurrentQueue<(DateTime Time, double RawValue, double DisplayValue)> DataPoints { get; } = new();
/// <summary>最大缓冲数据点数,超出则丢弃最旧的</summary>
public int MaxBuffer { get; set; } = 5000;
// ===== OxyPlot Series仅 IsDisplayed=true 时存在)=====
private LineSeries? _series;
public LineSeries? Series
{
get => _series;
set => SetProperty(ref _series, value);
}
// ===== 辅助方法 =====
/// <summary>记录一个数据点RawValue 经数学变换后得到 DisplayValue一并入队</summary>
public void Record(DateTime time, double rawValue)
{
double displayValue = rawValue;
DataPoints.Enqueue((time, rawValue, displayValue));
// 超出缓冲上限时批量丢弃旧数据
while (DataPoints.Count > MaxBuffer)
{
DataPoints.TryDequeue(out _);
}
// 如果正在显示,同步到 Series
if (_series != null)
{
_series.Points.Add(new DataPoint(time.ToOADate(), displayValue));
while (_series.Points.Count > 10000)
{
_series.Points.RemoveAt(0);
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
namespace UIShare.UIViewModel
{
/// <summary>
/// 监测通道持久化配置(用于 JSON 保存/恢复)。
/// </summary>
public class MonitorChannelConfig
{
/// <summary>硬件指纹(物理设备唯一标识)</summary>
public string Fingerprint { get; set; } = string.Empty;
/// <summary>监测方法名</summary>
public string MethodName { get; set; } = string.Empty;
/// <summary>是否在图表上显示该通道的线图</summary>
public bool IsDisplayed { get; set; } = true;
}
}

View File

@@ -0,0 +1,311 @@
using Newtonsoft.Json;
using Prism.Mvvm; // 引入 Prism 的 BindableBase
using System;
using System.Collections.Generic;
namespace UIShare.UIViewModel
{
public class ParameterVM : BindableBase
{
#region
public ParameterVM()
{
}
public ParameterVM(ParameterVM source)
{
if (source == null) return;
ID = source.ID;
Name = source.Name;
Type = source.Type;
Category = source.Category;
IsUseVar = source.IsUseVar;
VariableName = source.VariableName;
VariableID = source.VariableID;
Value = source.Value;
LowerLimit = source.LowerLimit;
UpperLimit = source.UpperLimit;
}
#endregion
private Guid _id = Guid.NewGuid();
public Guid ID
{
get => _id;
set => SetProperty(ref _id, value);
}
private bool _isVisible = true;
public bool IsVisible
{
get => _isVisible;
set => SetProperty(ref _isVisible, value);
}
private bool _isEditable = true;
public bool IsEditable
{
get => _isEditable;
set => SetProperty(ref _isEditable, value);
}
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private Type _type = typeof(string);
public Type Type
{
get => _type;
set => SetProperty(ref _type, value);
}
private ParameterCategory _category = ParameterCategory.Temp;
public ParameterCategory Category
{
get => _category;
set => SetProperty(ref _category, value);
}
private object? _value;
public object? Value
{
get => _value;
set => SetProperty(ref _value, value);
}
private object? _lowerLimit;
public object? LowerLimit
{
get => _lowerLimit;
set => SetProperty(ref _lowerLimit, value);
}
private object? _upperLimit;
public object? UpperLimit
{
get => _upperLimit;
set => SetProperty(ref _upperLimit, value);
}
private bool _result = true;
public bool Result
{
get => _result;
set => SetProperty(ref _result, value);
}
private bool _isUseVar;
public bool IsUseVar
{
get => _isUseVar;
set => SetProperty(ref _isUseVar, value);
}
private string? _variableName;
public string? VariableName
{
get => _variableName;
set => SetProperty(ref _variableName, value);
}
private Guid? _variableID;
public Guid? VariableID
{
get => _variableID;
set => SetProperty(ref _variableID, value);
}
public enum ParameterCategory
{
Input,
Output,
Temp
}
public object? GetActualValue(Dictionary<Guid, ParameterVM> paraList)
{
HashSet<Guid> visitedIds = new HashSet<Guid>();
ParameterVM current = this;
while (current != null)
{
if (!current.IsUseVar)
{
return current.Value;
}
if (visitedIds.Contains(current.ID))
{
return null;
}
visitedIds.Add(current.ID);
if (current.VariableID == null)
{
if (Type != null && Value != null)
{
try
{
return Convert.ChangeType(Value, Type);
}
catch
{
return Value;
}
}
}
ParameterVM? next = paraList[(Guid)current.VariableID!];
if (next == null)
{
return null;
}
current = next;
}
return null;
}
public ParameterVM? GetCurrentParameter(Dictionary<Guid, ParameterVM> paraList)
{
HashSet<Guid> visitedIds = new HashSet<Guid>();
ParameterVM current = this;
while (current != null)
{
if (current.VariableID == null)
{
return current;
}
if (visitedIds.Contains(current.ID))
{
return null;
}
visitedIds.Add(current.ID);
if (current.VariableID == null)
{
if (Type != null && Value != null)
{
try
{
return current;
}
catch
{
return null;
}
}
}
ParameterVM? next = paraList[(Guid)current.VariableID!];
if (next == null)
{
return null;
}
current = next;
}
return null;
}
public (bool, string?) GetResult()
{
if (Type == typeof(string) && (!string.IsNullOrWhiteSpace(LowerLimit?.ToString()) || !string.IsNullOrWhiteSpace(UpperLimit?.ToString())))
{
return (true, $"参数 [ {Name}({Type}) ] 不可比较");
}
if (Value == null || (LowerLimit == null && UpperLimit == null))
{
return (true, null);
}
if (string.IsNullOrWhiteSpace(Value?.ToString()) || (string.IsNullOrWhiteSpace(LowerLimit?.ToString()) && string.IsNullOrWhiteSpace(UpperLimit?.ToString())))
{
return (true, null);
}
try
{
object? comparableValue = ConvertToComparable(Value);
object? comparableLower = LowerLimit != null ? ConvertToComparable(LowerLimit) : null;
object? comparableUpper = UpperLimit != null ? ConvertToComparable(UpperLimit) : null;
if (comparableValue == null)
{
return (true, $"参数 [ {Name}({Type}) ] 不可比较");
}
bool lowerValid = true;
bool upperValid = true;
if (comparableLower != null)
{
lowerValid = CompareValues(comparableValue, comparableLower) >= 0;
}
if (comparableUpper != null)
{
upperValid = CompareValues(comparableValue, comparableUpper) <= 0;
}
return (lowerValid && upperValid, null);
}
catch (Exception ex)
{
return (true, $"参数 [ {Name}({Type}) ] 上下限比较失败:{ex.Message}");
}
}
private static object? ConvertToComparable(object value)
{
if (value is IConvertible convertible)
{
try
{
return convertible.ToDouble(null);
}
catch { }
try
{
return convertible.ToDateTime(null);
}
catch { }
}
return null;
}
private static int CompareValues(object a, object b)
{
if (a is double aDouble && b is double bDouble)
{
return aDouble.CompareTo(bDouble);
}
if (a is DateTime aDate && b is DateTime bDate)
{
return aDate.CompareTo(bDate);
}
return 0;
}
}
}

View File

@@ -0,0 +1,51 @@
using Prism.Mvvm; // 引入 Prism 的 BindableBase
using System;
using System.Collections.ObjectModel;
using System.Linq;
namespace UIShare.UIViewModel
{
public class ProgramVM : BindableBase
{
#region
public ProgramVM()
{
// 可以进行初始化操作
}
public ProgramVM(ProgramVM source)
{
ID = source.ID;
StepCollection = new ObservableCollection<StepVM>(source.StepCollection.Select(p => new StepVM(p)));
ErrorStepCollection = new ObservableCollection<StepVM>(source.ErrorStepCollection.Select(p => new StepVM(p)));
Parameters = new ObservableCollection<ParameterVM>(source.Parameters.Select(p => new ParameterVM(p)));
}
#endregion
public Guid ID { get; set; } = Guid.NewGuid();
private ObservableCollection<StepVM> _stepCollection = new ObservableCollection<StepVM>();
public ObservableCollection<StepVM> StepCollection
{
get => _stepCollection;
set => SetProperty(ref _stepCollection, value);
}
private ObservableCollection<StepVM> _errorStepCollection = new ObservableCollection<StepVM>();
public ObservableCollection<StepVM> ErrorStepCollection
{
get => _errorStepCollection;
set => SetProperty(ref _errorStepCollection, value);
}
private ObservableCollection<ParameterVM> _parameters = new ObservableCollection<ParameterVM>();
public ObservableCollection<ParameterVM> Parameters
{
get => _parameters;
set => SetProperty(ref _parameters, value);
}
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UIShare.UIViewModel
{
/// <summary>
/// 串口连接配置(与 DeviceCommand.Base.Serial_Port 保持字段一致)。
/// StopBits / Parity 用字符串保存,避免 UIShare 引入 System.IO.Ports 依赖。
/// </summary>
public class SerialPortConfigVM : BindableBase
{
private string _portName = "COM1";
public string PortName
{
get => _portName;
set => SetProperty(ref _portName, value);
}
private int _baudRate = 9600;
public int BaudRate
{
get => _baudRate;
set => SetProperty(ref _baudRate, value);
}
private int _dataBits = 8;
public int DataBits
{
get => _dataBits;
set => SetProperty(ref _dataBits, value);
}
// 取值:"One" / "OnePointFive" / "Two" / "None"
private string _stopBits = "One";
public string StopBits
{
get => _stopBits;
set => SetProperty(ref _stopBits, value);
}
// 取值:"None" / "Odd" / "Even" / "Mark" / "Space"
private string _parity = "None";
public string Parity
{
get => _parity;
set => SetProperty(ref _parity, value);
}
private int _readTimeout = 3000;
public int ReadTimeout
{
get => _readTimeout;
set => SetProperty(ref _readTimeout, value);
}
private int _writeTimeout = 3000;
public int WriteTimeout
{
get => _writeTimeout;
set => SetProperty(ref _writeTimeout, value);
}
public SerialPortConfigVM() { }
public SerialPortConfigVM(SerialPortConfigVM? src)
{
if (src == null) return;
PortName = src.PortName;
BaudRate = src.BaudRate;
DataBits = src.DataBits;
StopBits = src.StopBits;
Parity = src.Parity;
ReadTimeout = src.ReadTimeout;
WriteTimeout = src.WriteTimeout;
}
public void CopyTo(SerialPortConfigVM? dst)
{
if (dst == null) return;
dst.PortName = PortName;
dst.BaudRate = BaudRate;
dst.DataBits = DataBits;
dst.StopBits = StopBits;
dst.Parity = Parity;
dst.ReadTimeout = ReadTimeout;
dst.WriteTimeout = WriteTimeout;
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UIShare.UIViewModel
{
public class SharedParameter:BindableBase
{
private string _id;
public string Id
{
get => _id;
set => SetProperty(ref _id, value);
}
private string _parameterName;
public string ParameterName
{
get => _parameterName;
set => SetProperty(ref _parameterName, value);
}
private int _value;
public int Value
{
get => _value;
set => SetProperty(ref _value, value);
}
}
}

View File

@@ -0,0 +1,178 @@
using Newtonsoft.Json;
using Prism.Mvvm; // 引入 Prism 的 BindableBase
using System;
namespace UIShare.UIViewModel
{
public class StepVM : BindableBase
{
#region
public StepVM() { }
public StepVM(StepVM source)
{
if (source == null) return;
ID = source.ID;
Index = source.Index;
Name = source.Name;
StepType = source.StepType;
LoopCount = source.LoopCount;
LoopStartStepId = source.LoopStartStepId;
OKExpression = source.OKExpression;
OKGotoStepID = source.OKGotoStepID;
GotoSettingString = source.GotoSettingString;
NGGotoStepID = source.NGGotoStepID;
Description = source.Description;
IsUsed = source.IsUsed;
if (source.Method != null)
{
Method = new MethodVM(source.Method);
}
if (source.SubProgram != null)
{
SubProgram = new ProgramVM(source.SubProgram);
}
}
#endregion
private Guid _id = Guid.NewGuid();
public Guid ID
{
get => _id;
set => SetProperty(ref _id, value);
}
private bool _isUsed = true;
public bool IsUsed
{
get => _isUsed;
set => SetProperty(ref _isUsed, value);
}
private int _index;
public int Index
{
get => _index;
set => SetProperty(ref _index, value);
}
private string? _name;
public string? Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private string? _stepType;
public string? StepType
{
get => _stepType;
set => SetProperty(ref _stepType, value);
}
private MethodVM? _method;
public MethodVM? Method
{
get => _method;
set => SetProperty(ref _method, value);
}
private ProgramVM? _subProgram;
public ProgramVM? SubProgram
{
get => _subProgram;
set => SetProperty(ref _subProgram, value);
}
private int? _loopCount;
public int? LoopCount
{
get => _loopCount;
set => SetProperty(ref _loopCount, value);
}
[JsonIgnore]
private int? _currentLoopCount;
[JsonIgnore]
public int? CurrentLoopCount
{
get => _currentLoopCount;
set => SetProperty(ref _currentLoopCount, value);
}
private Guid? _loopStartStepId;
public Guid? LoopStartStepId
{
get => _loopStartStepId;
set => SetProperty(ref _loopStartStepId, value);
}
[JsonIgnore]
private int _result = -1;
[JsonIgnore]
public int Result
{
get => _result;
set => SetProperty(ref _result, value);
}
[JsonIgnore]
private int? _runTime;
[JsonIgnore]
public int? RunTime
{
get => _runTime;
set => SetProperty(ref _runTime, value);
}
private string? _okExpression;
public string? OKExpression
{
get => _okExpression;
set => SetProperty(ref _okExpression, value);
}
private string _gotoSettingString = "";
public string GotoSettingString
{
get => _gotoSettingString;
set => SetProperty(ref _gotoSettingString, value);
}
private Guid? _okGotoStepID;
public Guid? OKGotoStepID
{
get => _okGotoStepID;
set => SetProperty(ref _okGotoStepID, value);
}
private Guid? _ngGotoStepID;
public Guid? NGGotoStepID
{
get => _ngGotoStepID;
set => SetProperty(ref _ngGotoStepID, value);
}
private string? _description;
public string? Description
{
get => _description;
set => SetProperty(ref _description, value);
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UIShare.UIViewModel
{
public class SubProgramItemVM : BindableBase
{
private string _name="";
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private string _filePath = "";
public string FilePath
{
get => _filePath;
set => SetProperty(ref _filePath, value);
}
}
}

View File

@@ -0,0 +1,62 @@
using Prism.Mvvm;
namespace UIShare.UIViewModel
{
/// <summary>
/// TCP 连接配置(与 DeviceCommand.Base.Tcp 保持字段一致)。
/// </summary>
public class TcpConfigVM : BindableBase
{
private string _ipAddress = "127.0.0.1";
public string IPAddress
{
get => _ipAddress;
set => SetProperty(ref _ipAddress, value);
}
private int _port = 502;
public int Port
{
get => _port;
set => SetProperty(ref _port, value);
}
private int _sendTimeout = 3000;
public int SendTimeout
{
get => _sendTimeout;
set => SetProperty(ref _sendTimeout, value);
}
private int _receiveTimeout = 3000;
public int ReceiveTimeout
{
get => _receiveTimeout;
set => SetProperty(ref _receiveTimeout, value);
}
public TcpConfigVM() { }
/// <summary>拷贝构造,用于对话框编辑副本。</summary>
public TcpConfigVM(TcpConfigVM? src)
{
if (src == null) return;
IPAddress = src.IPAddress;
Port = src.Port;
SendTimeout = src.SendTimeout;
ReceiveTimeout = src.ReceiveTimeout;
}
/// <summary>把字段拷回目标对象(保存时用)。</summary>
public void CopyTo(TcpConfigVM? dst)
{
if (dst == null) return;
dst.IPAddress = IPAddress;
dst.Port = Port;
dst.SendTimeout = SendTimeout;
dst.ReceiveTimeout = ReceiveTimeout;
}
}
}

View File

@@ -0,0 +1,117 @@
using Prism.Mvvm;
namespace UIShare.UIViewModel
{
// 继承 BindableBase 使得属性变更时能实时通知 UI 刷新
public class ValueLimitVM : BindableBase
{
private string _signalName = string.Empty;
private string _fingerprint = string.Empty;
private string _methodName = string.Empty;
private string _displayName = string.Empty;
private double _upper;
private double _lower;
private double _upperExtreme;
private double _lowerExtreme;
private bool _isAlarm = false;
private AlarmStatus _alarmStatus = AlarmStatus.;
/// <summary>
/// 信号名(显示用)
/// </summary>
public string SignalName
{
get => _signalName;
set => SetProperty(ref _signalName, value);
}
/// <summary>
/// 信号名(显示用)
/// </summary>
public string DisplayName
{
get => _displayName;
set => SetProperty(ref _displayName, value);
}
/// <summary>
/// 硬件指纹(物理设备唯一标识,用于超限匹配)
/// </summary>
public string Fingerprint
{
get => _fingerprint;
set => SetProperty(ref _fingerprint, value);
}
/// <summary>
/// 方法名(唯一标识,用于超限匹配)
/// </summary>
public string MethodName
{
get => _methodName;
set => SetProperty(ref _methodName, value);
}
/// <summary>
/// 上限
/// </summary>
public double Upper
{
get => _upper;
set => SetProperty(ref _upper, value);
}
/// <summary>
/// 下限
/// </summary>
public double Lower
{
get => _lower;
set => SetProperty(ref _lower, value);
}
/// <summary>
/// 上极限
/// </summary>
public double UpperExtreme
{
get => _upperExtreme;
set => SetProperty(ref _upperExtreme, value);
}
/// <summary>
/// 下极限
/// </summary>
public double LowerExtreme
{
get => _lowerExtreme;
set => SetProperty(ref _lowerExtreme, value);
}
/// <summary>
/// 是否报警
/// </summary>
public bool IsAlarm
{
get => _isAlarm;
set => SetProperty(ref _isAlarm, value);
}
/// <summary>
/// 警报状态类型
/// </summary>
public AlarmStatus AlarmSatus
{
get => _alarmStatus;
set => SetProperty(ref _alarmStatus, value);
}
}
public enum AlarmStatus
{
= 0, // 未报警
= 1, // 超上限
= 2, // 超下限
= 3, // 超上极限
= 4, // 超下极限
}
}