Files
shgxtzcjhoudaosaomadayinwpf/RIZO_Application/Modules/RIZO_Application.Modules.ModuleName/ViewModels/ScanControlViewModel.cs
2025-05-15 11:22:42 +08:00

177 lines
5.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Threading.Tasks;
using System.Windows.Media;
using Prism.Events;
using Prism.Regions;
using RIZO_Application.Core;
using RIZO_Application.Core.Mvvm;
using RIZO_Application.Infrastructure.Model;
using RIZO_Helper.Tools;
using System.Windows;
using System.IO.Ports;
using System.Windows.Documents;
namespace RIZO_Application.Modules.ModuleName.ViewModels
{
public class ScanControlViewModel : RegionViewModelBase, IDisposable
{
private readonly IEventAggregator _eventAggregator;
private ComScanHelper _scanHelper;
private bool _isDisposed;
private bool _isConnected;
private string _lastLabel;
private DateTime _lastScanTime;
// 串口连接状态属性
public bool IsConnected
{
get => _isConnected;
set
{
if (SetProperty(ref _isConnected, value))
{
// 通知依赖属性更新
RaisePropertyChanged(nameof(ConnectionStatusText));
RaisePropertyChanged(nameof(ConnectionStatusForeground));
}
}
}
// 串口连接状态文字描述
public string ConnectionStatusText
{
get => IsConnected ? "扫码枪已连接" : "扫码枪未连接";
}
// 串口连接状态文字颜色
public Brush ConnectionStatusForeground
{
get => IsConnected ? Brushes.Green : Brushes.Red;
}
public ScanControlViewModel(
IRegionManager regionManager,
IEventAggregator eventAggregator)
: base(regionManager)
{
_eventAggregator = eventAggregator;
IsConnected = false; // 初始状态为未连接
InitializeScanHelperAsync().ConfigureAwait(false);
}
private async Task InitializeScanHelperAsync()
{
try
{
await StartComScan();
}
catch (Exception ex)
{
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"串口初始化异常: {ex.Message}");
}
}
public async Task StartComScan()
{
if (_isDisposed)
throw new ObjectDisposedException(nameof(ScanControlViewModel));
string comName = "COM1";
int baudRate = 9600;
if (SerialConfigs.Current != null)
{
comName = SerialConfigs.Current.ComName ?? string.Empty;
baudRate = SerialConfigs.Current.BaudRate ?? 9600;
}
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"串口扫码枪初始化……串口:{comName} 波特率:{baudRate}");
// 安全地释放现有实例
await DisposeScanHelperAsync();
_scanHelper = new ComScanHelper(comName, baudRate);
_scanHelper.DataReceived += HandleMessage;
_scanHelper.ErrorOccurred += HandleError;
if (await _scanHelper.OpenAsync())
{
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"串口扫码初始化完成");
IsConnected = true; // 连接成功
}
else
{
MessageBox.Show($"打开串口失败");
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"串口打开失败");
IsConnected = false; // 连接失败
}
}
private void HandleError(object sender, Exception ex)
{
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"串口通信错误: {ex.Message}");
IsConnected = false; // 发生错误时断开连接
}
// 定义事件处理方法
private void HandleMessage(object sender, string labelCode)
{
DateTime now = DateTime.Now;
// 短时间内重复扫了同一个标签时间间隔小于500毫秒
if (_lastLabel!= null && _lastLabel == labelCode && (now - _lastScanTime).TotalMilliseconds < 500)
{
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"重复扫码过滤: {labelCode}");
return;
}
_lastLabel = labelCode;
_lastScanTime = now;
// 打印接收到的消息信息
//_eventAggregator.GetEvent<SystemLogEvent>().Publish($"收到串口信息: {labelCode}");
_eventAggregator.GetEvent<ScanEvent>().Publish(labelCode);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private async void Dispose(bool disposing)
{
if (_isDisposed)
return;
_isDisposed = true;
if (disposing)
{
await DisposeScanHelperAsync();
}
}
private async Task DisposeScanHelperAsync()
{
if (_scanHelper != null)
{
try
{
_scanHelper.DataReceived -= HandleMessage;
_scanHelper.ErrorOccurred -= HandleError;
await _scanHelper.DisposeAsync();
}
catch (Exception ex)
{
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"释放串口资源异常: {ex.Message}");
}
finally
{
_scanHelper = null;
IsConnected = false; // 释放资源后断开连接
}
}
}
~ScanControlViewModel()
{
Dispose(false);
}
}
}