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
{
///
/// 这是CoilUC的VM用来支持数据绑定
///
public class CoilUCViewModel : BindableBase,IDisposable
{
// 标记是否已释放资源
private bool _disposed = false;
//事件聚合器
private readonly IEventAggregator _eventAggregator;
//定义数据库操作
private ModbusDbContext _modbusDbContext;
//获取读线圈的类
private IModbusRTU _modbusRTU;
//定义读线圈的命令
public DelegateCommand ReadCoilCmm { get; set; }
//定义写线圈操作
public DelegateCommand WriteCoilCmm { 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;
}
}
#endregion
private List _modbusLogList;
public List ModbusLogList
{
get { return _modbusLogList; }
set
{
_modbusLogList = value;
RaisePropertyChanged();
}
}
public CoilUCViewModel()
{
}
public CoilUCViewModel(SerialPort serialPort, ModbusRTU modbusRTU, ModbusDbContext modbusDbContext, IEventAggregator eventAggregator)
{
_serialPort = serialPort;
ReadCoilCmm = new DelegateCommand(ReadCoil);
_modbusRTU = modbusRTU;
WriteCoilCmm = new DelegateCommand(WriteCoil);
_modbusDbContext = modbusDbContext;
_eventAggregator = eventAggregator;
// 订阅事件(使用弱引用,避免内存泄漏)
_eventAggregator.GetEvent().Subscribe(
OnSerialPortSettingsChanged,
ThreadOption.UIThread, // 在UI线程执行回调
false);// 不使用强引用
//初始化查询操作
ModbusLogList = GetOperateCoil();
IsEnable = true;
}
// 事件回调方法:当串口设置变更时触发
private void OnSerialPortSettingsChanged()
{
// 强制刷新SerialPortInfo属性,触发UI更新
RaisePropertyChanged(nameof(SerialPortInfo));
}
///
/// 线圈读取操作
///
private void ReadCoil()
{
//检测当前输入的信息是否正确
var validation = CheckInputUitl.ValidateReadParameters(SlaveAddress, StartAddress, NumberOfPoints);
if (!validation.success)
{
return;
}
//使用子线程,防止ui线程卡顿
Task.Run(() =>
{
IsEnable = false;
bool[] result = _modbusRTU.ReadCoil(validation.slaveAddress, validation.startAddress, validation.numberOfPoints);
if (result == null)
{
MessageBox.Show("读取失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
ModbusLogList = GetOperateCoil();
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 = GetOperateCoil();
});
}
private void WriteCoil()
{
//检测当前输入的信息是否正确
var validation = CheckInputUitl.ValidateWriteParameters(WriteSlaveAddress, WriteStartAddress,WriteData);
if (!validation.success)
{
return;
}
//去除字符串中的空格
WriteData = WriteData.Replace(" ", "");
//转换为布尔数组
bool[] data = WriteData.Select(m => m == '1').ToArray();
//使用子线程执行,避免ui线程卡顿
Task.Run(() =>
{
IsEnable = false;
bool issucceed = _modbusRTU.WriteCoil(validation.slaveAddress, validation.startAddress, data);
ModbusLogList = GetOperateCoil();
if (issucceed)
{
MessageBox.Show("写入成功");
}
else
{
MessageBox.Show("写入失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
}
IsEnable = true;
});
}
///
/// 获取展示数据
///
///
private List GetOperateCoil()
{
return _modbusDbContext.ModbusLog
.Where(log => log.OperationType == "读线圈" || log.OperationType == "写线圈")
.OrderByDescending(log => log.Time) // 按时间倒序,最新的在前
.Take(30) // 只取前20条记录
.ToList(); // 执行查询
}
///
/// 释放资源
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// 真实调用的方法
///
///
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; // 标记为已释放
}
}
}