Files
ADP/SettingModule/ViewModels/Dialogs/SerialPortConfigViewModel.cs
2026-06-10 16:05:35 +08:00

165 lines
5.0 KiB
C#
Raw Permalink 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.Collections.ObjectModel;
using System.IO.Ports;
using System.Linq;
using System.Windows.Input;
using UIShare.PubEvent;
using UIShare.UIViewModel;
using UIShare.ViewModelBase;
namespace SettingModule.ViewModels.Dialogs
{
/// <summary>
/// 串口连接配置对话框 VM。
/// 通过 DialogParameters 接收宿主 DeviceInfoVM保存时把副本写回宿主。
/// </summary>
public class SerialPortConfigViewModel : DialogViewModelBase
{
#region
private string _title = "串口连接配置";
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
private SerialPortConfigVM _config = new();
public SerialPortConfigVM Config
{
get => _config;
set => SetProperty(ref _config, value);
}
/// <summary>当前可用串口列表OnDialogOpened 刷新)。</summary>
public ObservableCollection<string> AvailablePorts { get; } = new();
public ObservableCollection<int> CommonBaudRates { get; } = new()
{
1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600
};
public ObservableCollection<int> DataBitsList { get; } = new() { 5, 6, 7, 8 };
public ObservableCollection<string> StopBitsList { get; } = new()
{
"One", "OnePointFive", "Two"
};
public ObservableCollection<string> ParityList { get; } = new()
{
"None", "Odd", "Even", "Mark", "Space"
};
public ObservableCollection<int> CommonTimeouts { get; } = new()
{
500, 1000, 2000, 3000, 5000, 10000
};
private string _errorMessage = string.Empty;
public string ErrorMessage
{
get => _errorMessage;
set => SetProperty(ref _errorMessage, value);
}
#endregion
#region
public ICommand SaveCommand { get; }
public ICommand CancelCommand { get; }
public ICommand RefreshPortsCommand { get; }
#endregion
private DeviceInfoVM? _hostDevice;
public SerialPortConfigViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
SaveCommand = new DelegateCommand(OnSave);
CancelCommand = new DelegateCommand(OnCancel);
RefreshPortsCommand = new DelegateCommand(RefreshPorts);
}
private void RefreshPorts()
{
AvailablePorts.Clear();
// 若当前选中的串口不在可用列表中,仍保留显示,便于离线编辑
if (!string.IsNullOrEmpty(Config.PortName) && !AvailablePorts.Contains(Config.PortName))
AvailablePorts.Insert(0, Config.PortName);
}
private bool Validate(out string error)
{
error = string.Empty;
if (string.IsNullOrWhiteSpace(Config.PortName))
{
error = "串口名称不能为空";
return false;
}
if (Config.BaudRate <= 0)
{
error = "波特率必须大于 0";
return false;
}
if (Config.DataBits < 5 || Config.DataBits > 8)
{
error = "数据位必须在 5 - 8 之间";
return false;
}
if (Config.ReadTimeout < 0 || Config.WriteTimeout < 0)
{
error = "超时时间不能为负数";
return false;
}
return true;
}
private void OnSave()
{
if (!Validate(out var error))
{
ErrorMessage = error;
return;
}
ErrorMessage = string.Empty;
if (_hostDevice != null)
{
_hostDevice.SerialPortConfig ??= new SerialPortConfigVM();
Config.CopyTo(_hostDevice.SerialPortConfig);
_hostDevice.ConnectionType = "Serial";
}
RequestClose.Invoke(ButtonResult.OK);
}
private void OnCancel() => RequestClose.Invoke(ButtonResult.Cancel);
#region Prism Dialog
public override void OnDialogOpened(IDialogParameters parameters)
{
_eventAggregator.GetEvent<OverlayEvent>().Publish(true);
if (parameters.ContainsKey("Device"))
{
_hostDevice = parameters.GetValue<DeviceInfoVM>("Device");
Title = $"串口连接配置 - {_hostDevice?.DeviceName}";
Config = new SerialPortConfigVM(_hostDevice?.SerialPortConfig);
}
else if (parameters.ContainsKey("Config"))
{
Config = new SerialPortConfigVM(parameters.GetValue<SerialPortConfigVM>("Config"));
}
RefreshPorts();
}
public override void OnDialogClosed()
{
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
}
#endregion
}
}