|
- using ModbusDemo.Device;
- using ModbusDemo.Event;
- using ModbusDemo.Model;
- using ModbusDemo.Uitls;
- using Prism.Commands;
- using Prism.Events;
- using Prism.Mvvm;
- using System;
- using System.Collections.Generic;
- using System.IO.Ports;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
-
- namespace ModbusDemo.VIewModel
- {
- class RegisterUCViewModel : BindableBase,IDisposable
- {
- // 标记是否已释放资源
- private bool _disposed = false;
- //事件聚合器
- private readonly IEventAggregator _eventAggregator;
- //定义数据库操作类
- private ModbusDbContext _modbusDbContext;
- //获取读线圈的类
- private IModbusRTU _modbusRTU;
- //定义读线圈的命令
- public DelegateCommand ReadRegisterCmm { get; set; }
- //定义写线圈操作
- public DelegateCommand WriteRegisterCmm { get; set; }
- //获取当前使用的串口
- private SerialPort _serialPort;
-
- //按钮是否可以点击
- private bool _isEnable;
-
- public bool IsEnable
- {
- get { return _isEnable; }
- set
- {
- _isEnable = value;
- RaisePropertyChanged();
- }
- }
-
- //显示当前链接串口的信息
- public string SerialPortInfo
- {
- get
- {
- return "当前为读写寄存器:" + "串口号:" + _serialPort.PortName + ",波特率:" + _serialPort.BaudRate
- + ",数据位:" + _serialPort.DataBits + ",校验位:" + _serialPort.Parity + ",停止位:" + _serialPort.StopBits;
- }
-
- }
- #region 读取定义
-
- //读取的从站id
- private string _slaveAddress;
-
- public string SlaveAddress
- {
- get { return _slaveAddress; }
- set
- {
- _slaveAddress = value;
- RaisePropertyChanged();
- }
- }
- //读取的起始地址
- private string _startAddress;
-
-
- public string StartAddress
- {
- get { return _startAddress; }
- set
- {
- _startAddress = value;
- RaisePropertyChanged();
- }
- }
- //读取的位数
- private string _numberOfPoints;
-
-
- public string NumberOfPoints
- {
- get { return _numberOfPoints; }
- set
- {
- _numberOfPoints = value;
- RaisePropertyChanged();
- }
- }
-
- private string _readResult;
-
- //读取的结果
- public string ReadResult
- {
- get { return _readResult; }
- set
- {
- _readResult = value;
- RaisePropertyChanged();
- }
- }
- #endregion
-
- #region 写入定义
-
- //写入的从站id
- private string _writeslaveAddress;
-
- public string WriteSlaveAddress
- {
- get { return _writeslaveAddress; }
- set
- {
- _writeslaveAddress = value;
- RaisePropertyChanged();
- }
- }
- //写入的起始地址
- private string _writestartAddress;
-
-
- public string WriteStartAddress
- {
- get { return _writestartAddress; }
- set
- {
- _writestartAddress = value;
- RaisePropertyChanged();
- }
- }
- //写入的数据
- private string _writeData;
-
-
- public string WriteData
- {
- get { return _writeData; }
- set
- {
- _writeData = value;
- RaisePropertyChanged();
- }
- }
-
-
- #endregion
-
- private List<ModbusLog> _modbusLogList;
-
- public List<ModbusLog> ModbusLogList
- {
- get { return _modbusLogList; }
- set
- {
- _modbusLogList = value;
- RaisePropertyChanged();
- }
- }
-
- public RegisterUCViewModel()
- {
-
- }
- public RegisterUCViewModel(SerialPort serialPort, ModbusRTU modbusRTU, ModbusDbContext modbusDbContext, IEventAggregator eventAggregator)
- {
- _serialPort = serialPort;
- ReadRegisterCmm = new DelegateCommand(ReadRegister);
- _modbusRTU = modbusRTU;
- WriteRegisterCmm = new DelegateCommand(WriteRegister);
- _modbusDbContext = modbusDbContext;
- _eventAggregator = eventAggregator;
- // 订阅事件(使用弱引用,避免内存泄漏)
- _eventAggregator.GetEvent<SerialPortSettingsChangedEvent>().Subscribe(
- OnSerialPortSettingsChanged,
- ThreadOption.UIThread, // 在UI线程执行回调
- false);// 不使用强引用
- ModbusLogList = GetOperateRegister();
-
- IsEnable = true;
- }
- // 事件回调方法:当串口设置变更时触发
- private void OnSerialPortSettingsChanged()
- {
- // 强制刷新SerialPortInfo属性,触发UI更新
- RaisePropertyChanged(nameof(SerialPortInfo));
- }
-
-
-
-
-
- /// <summary>
- /// 线圈读取操作
- /// </summary>
- private void ReadRegister()
- {
- //检测当前输入的信息是否正确
- var validation = CheckInputUitl.ValidateReadParameters(SlaveAddress, StartAddress, NumberOfPoints);
- if (!validation.success)
- {
- return;
- }
- //使用子线程进行读取,防止ui线程卡顿
- Task.Run(() =>
- { IsEnable = false;
- ushort[] result = _modbusRTU.ReadRegister(validation.slaveAddress, validation.startAddress, validation.numberOfPoints);
- if (result == null)
- {
- MessageBox.Show("读取失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
- ModbusLogList = GetOperateRegister();
- IsEnable = true;
- return;
- }
- string temp = "";
- int count = 0;
- foreach (var item in result)
- {
- count++;
- temp += item;
- temp += " ";
- if (count % 25 == 0)
- {
- temp += "\n";
- }
- }
- ReadResult = temp;
- MessageBox.Show("读取成功");
- IsEnable = true;
- ModbusLogList = GetOperateRegister();
- });
-
- }
-
-
-
- private void WriteRegister()
- {
- //检测当前输入的信息是否正确
- var validation = CheckInputUitl.ValidateWriteParameters(WriteSlaveAddress, WriteStartAddress, WriteData);
- if (!validation.success)
- {
- return;
- }
- string[] parts = WriteData.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
- // 创建结果数组
- ushort[] data = new ushort[parts.Length];
-
- // 遍历并转换每个部分
- for (int i = 0; i < parts.Length; i++)
- {
- // 尝试解析为ushort
- if (ushort.TryParse(parts[i], out ushort value))
- {
- data[i] = value;
- }
- else
- {
-
- MessageBox.Show($"无法将 '{parts[i]}' 转换为 ushort 类型");
-
- return;
- }
- }
-
- //使用子线程来去执行操作,防止ui线程卡顿
- Task.Run(() =>
- {
- IsEnable = false;
- bool issucceed = _modbusRTU.WriteRegister(validation.slaveAddress, validation.startAddress, data);
- ModbusLogList = GetOperateRegister();
-
- if (issucceed)
- {
- MessageBox.Show("写入成功");
- IsEnable = true;
- }
- else
- {
- MessageBox.Show("写入失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
- IsEnable = true;
- }
- });
-
-
-
-
- }
- /// <summary>
- /// 获取展示数据
- /// </summary>
- /// <returns></returns>
- private List<ModbusLog> GetOperateRegister()
- {
- return _modbusDbContext.ModbusLog
- .Where(log => log.OperationType == "读寄存器" || log.OperationType == "写寄存器")
- .OrderByDescending(log => log.Time) // 按时间倒序,最新的在前
- .Take(30) // 只取前20条记录
- .ToList(); // 执行查询
- }
-
- /// <summary>
- /// 释放资源
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <summary>
- /// 真实调用的方法
- /// </summary>
- /// <param name="disposing"></param>
- protected virtual void Dispose(bool disposing)
- {
- if (_disposed)
- return; // 避免重复释放
-
- // 释放托管资源(仅在手动调用Dispose时执行)
- if (disposing)
- {
-
- //_serialPort是单例的,不要手动释放
-
- // 释放数据库上下文是瞬态的需要手动释放
- if (_modbusDbContext != null)
- {
- _modbusDbContext.Dispose();
- _modbusDbContext = null;
- }
- if (_modbusRTU != null)
- {
- _modbusRTU.Dispose();
- _modbusRTU = null;
- }
- }
-
-
-
-
- _disposed = true; // 标记为已释放
- }
- }
- }
|