using MV485.Dlg;
using MV485.helper;
using MV485.model;
using MV485.util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Path = System.IO.Path;
namespace MV485.uc
{
///
/// UCDeviceConfig.xaml 的交互逻辑
///
public partial class UCDeviceConfig : UserControl
{
private static readonly string LogFilePath =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Documents", "config_log.txt");
private RWBasicConfig _rwBaseConfig = null;
private List _logEntries = new List();
private BasicConfig _readConfig;
public UCDeviceConfig()
{
InitializeComponent();
InitLoad();
LoadConfigLog();
}
//初始化加载
private void LoadSerialPorts()
{
Dispatcher.BeginInvoke(new Action(() =>
{
cmbPortNames.ItemsSource = SerialHelper.GetSerialPortsWithDetails();
if (cmbPortNames.Items.Count > 0)
cmbPortNames.SelectedIndex = 0;
var portName = ConfigManager.Instance.GetConfigValue(ConfigKey.ConfigPortName, "");
cmbPortNames.SelectedValue = portName;
}));
}
private void InitLoad()
{
//与设备通信的参数
cmbBaudrate.ItemsSource = SerialHelper.BaudRates;
var baudrates = ConfigManager.Instance.GetConfigValue(ConfigKey.ConfigBaudrate, "9600");
cmbBaudrate.SelectedValue = baudrates;
cmbDevId.ItemsSource = Enumerable.Range(1, 247).ToList();
var devId = ConfigManager.Instance.GetConfigValue(ConfigKey.ConfigDevId, "1");
cmbDevId.Text = devId;
//从设备读取或要设置的参数
cmbDevBaudrate.ItemsSource = SerialHelper.BaudRates;
cmbDevAddress.ItemsSource = Enumerable.Range(1, 247).ToList();
LoadSerialPorts();
InitConfiView();
}
private void btnRefreshPorts_Click(object sender, RoutedEventArgs e)
{
LoadSerialPorts();
AppendLog("串口列表已刷新");
}
private void CmbPortNames_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//var portName = cmbPortNames.SelectedValue.ToString();
//ConfigManager.Instance.UpdateConfig(ConfigKey.ConfigPortName, portName);
}
private async void BtnReadConfig_Click(object sender, RoutedEventArgs e)
{
//串口号
if(cmbPortNames.SelectedItem == null)
{
MessageBox.Show(Application.Current.MainWindow, "请选择串口", "提示",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var portName = cmbPortNames.SelectedValue.ToString();
ConfigManager.Instance.UpdateConfig(ConfigKey.ConfigPortName, portName);
//波特率
if(cmbBaudrate.SelectedItem == null)
{
MessageBox.Show(Application.Current.MainWindow, "请选择波特率", "提示",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var sBaudrate = cmbBaudrate.SelectedValue.ToString();
ConfigManager.Instance.UpdateConfig(ConfigKey.ConfigBaudrate, sBaudrate);
if(!byte.TryParse(cmbDevId.Text,out byte devid) || devid < 0 || devid > 247){
MessageBox.Show(Application.Current.MainWindow, "请输入正确的设备地址", "提示",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
ConfigManager.Instance.UpdateConfig(ConfigKey.ConfigDevId, devid.ToString());
//开始读取RS485设备的参数
_rwBaseConfig = new RWBasicConfig();
int baudrate = int.Parse(sBaudrate);
//显示等待串口
string titleInfo = "正在读取设备的基本参数";
WaitWindow waitWindow = new WaitWindow(titleInfo)
{
Owner = Application.Current.MainWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
waitWindow.Show();
InitConfiView();
try
{
_rwBaseConfig = new RWBasicConfig();
_rwBaseConfig.RWLog += _rwBaseConfig_RWLog;
_rwBaseConfig.SerialConnected += _rwBaseConfig_SerialConnected;
_rwBaseConfig.SerialStatusChanged += _rwBaseConfig_SerialStatusChanged;
BasicConfig basicConfig = await Task.Run(() => _rwBaseConfig.ReadBasicConfig(portName, baudrate, devid));
_readConfig = basicConfig; //记录读取的配置
if (basicConfig != null)
{
LoadViewWithBasicConfig(basicConfig);
cmbDevBaudrate.IsEnabled = true;
cmbDevAddress.IsEnabled = true;
txtResult.Text = "已成功读取设备参数";
txtResult.Foreground = Brushes.Green;
AppendLog("已成功读取设备参数");
}
else
{
txtResult.Text = "读取设备参数失败";
txtResult.Foreground = Brushes.Red;
AppendLog("读取设备参数失败");
}
}
catch { }
finally
{
waitWindow.Close();
}
}
//根据配置值加载页面
private void LoadViewWithBasicConfig(BasicConfig config)
{
InitConfiView();
txtDevType.Text = config.DeviceType;
txtDevSn.Text = config.DeviceSn;
txtFireware.Text = config.FireWare;
txtParty.Text = config.ParityName;
txtDataBits.Text = config.DataBitsName;
txtStopBits.Text = config.StopbitsName;
cmbDevBaudrate.SelectedValue = config.BaudRate.ToString();
cmbDevAddress.Text = config.DeviceAddress.ToString();
btnSetConifg.IsEnabled = true;
//cmbDevBaudrate.IsEnabled = true;
//cmbDevAddress.IsEnabled = true;
}
private void InitConfiView()
{
txtDevType.Text = "";
txtDevSn.Text = "";
txtFireware.Text = "";
txtParty.Text = "";
txtDataBits.Text = "";
txtStopBits.Text = "";
cmbDevBaudrate.SelectedItem = null;
cmbDevAddress.Text = "";
cmbDevBaudrate.IsEnabled = false;
cmbDevAddress.IsEnabled = false;
txtResult.Text = "";
btnSetConifg.IsEnabled = false;
}
private void _rwBaseConfig_RWLog(string message)
{
AppendLog(message);
}
private void _rwBaseConfig_SerialConnected(bool obj)
{
//throw new NotImplementedException();
}
private void _rwBaseConfig_SerialStatusChanged(bool obj)
{
//throw new NotImplementedException();
}
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (e.Text.All(char.IsDigit))
{
e.Handled = false; // 如果是数字,允许输入
}
else
{
// 如果当前输入的字符不是数字,并且是中文输入法的拼音或候选字,禁止输入
e.Handled = true;
}
}
private async void BtnSetConifg_Click(object sender, RoutedEventArgs e)
{
if (!LicenseMana.mIsLicensed)
{
MessageBox.Show(Application.Current.MainWindow, "软件未注册,不能使用此功能。", "提示",
MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
//bool isRead = _rwBaseConfig?.IsRead ?? false;
//if (!isRead)
if(_readConfig == null)
{
MessageBox.Show(Application.Current.MainWindow, "请先读取参数", "提示",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if(cmbDevBaudrate.SelectedItem == null)
{
MessageBox.Show(Application.Current.MainWindow, "请选择波特率", "提示",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var sBaudrate = cmbBaudrate.SelectedValue.ToString();
if (!byte.TryParse(cmbDevAddress.Text, out byte devAddress) || devAddress < 0 || devAddress > 247)
{
MessageBox.Show(Application.Current.MainWindow, "请输入正确的设备地址", "提示",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
string sBaudRate = cmbDevBaudrate.SelectedValue.ToString();
int baudRate = int.Parse(sBaudRate);
BasicConfig writeConfig = new BasicConfig()
{
BaudRate = baudRate,
DeviceAddress = devAddress
};
//判断是否有变化
if(_readConfig.BaudRate == writeConfig.BaudRate &&
_readConfig.DeviceAddress == writeConfig.DeviceAddress)
{
MessageBox.Show(Application.Current.MainWindow, "设置值与读取值无变化,设置无效", "提示",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
//显示等待串口
string titleInfo = "正在设置设备的基本参数";
WaitWindow waitWindow = new WaitWindow(titleInfo)
{
Owner = Application.Current.MainWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
waitWindow.Show();
//InitConfiView();
//btnSetConifg.IsEnabled = false;
try
{
bool blSuccess= await Task.Run(() => _rwBaseConfig.WriteBasicConfig(_readConfig,writeConfig));
//bool blSuccess = await _rwBaseConfig.WriteBasicConfig(_readConfig, writeConfig);
if (blSuccess)
{
cmbDevBaudrate.IsEnabled = true;
cmbDevAddress.IsEnabled = true;
txtResult.Text = "已成功设置设备参数";
txtResult.Foreground = Brushes.Green;
AppendLog("已成功设置设备参数");
//自动回填读参数列表
if (chkFillReadParams.IsChecked == true)
{
if(_readConfig.BaudRate != writeConfig.BaudRate)
{
cmbBaudrate.SelectedValue = writeConfig.BaudRate.ToString();
AppendLog($"回填波特率{_readConfig.BaudRate}->{writeConfig.BaudRate}");
}
if(_readConfig.DeviceAddress != writeConfig.DeviceAddress)
{
cmbDevId.Text = writeConfig.DeviceAddress.ToString();
AppendLog($"回填设备地址{_readConfig.DeviceAddress}->{writeConfig.DeviceAddress}");
}
_readConfig.BaudRate = writeConfig.BaudRate;
_readConfig.DeviceAddress = writeConfig.DeviceAddress;
btnSetConifg.IsEnabled = true;
}
else
{
cmbDevBaudrate.IsEnabled = false;
cmbDevAddress.IsEnabled = false;
btnSetConifg.IsEnabled = false;
_readConfig = null;
}
}
else
{
txtResult.Text = "设置设备参数失败";
txtResult.Foreground = Brushes.Red;
AppendLog("设置设备参数失败");
btnSetConifg.IsEnabled = true;
}
}
catch { }
finally
{
waitWindow.Close();
}
}
private void btnClearLog_Click(object sender, RoutedEventArgs e)
{
_logEntries.Clear();
lvLogs.ItemsSource = null;
File.WriteAllText(LogFilePath, "");
AppendLog("日志已清空");
}
private void AppendLog(string message)
{
Dispatcher.Invoke(() =>
{
var logEntry = new LogEntry { Time = DateTime.Now.ToString("HH:mm:ss.fff"), Message = message };
_logEntries.Add(logEntry);
lvLogs.ItemsSource = null;
lvLogs.ItemsSource = _logEntries;
lvLogs.ScrollIntoView(logEntry);
// 确保 Logs 目录存在
Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath));
//File.AppendAllText("config_log.txt", $"{logEntry.Time} - {logEntry.Message}\n");
// 追加日志
File.AppendAllText(LogFilePath, $"{logEntry.Time} - {logEntry.Message}\n");
});
}
//读取并加载日志
private void LoadConfigLog()
{
Dispatcher.BeginInvoke(new Action(() =>
{
LoadLogs();
}));
}
private void LoadLogs()
{
if (!File.Exists(LogFilePath))
return;
_logEntries.Clear(); // 先清空已有的日志记录
//var lines = File.ReadAllLines("config_log.txt");
var lines = File.ReadAllLines(LogFilePath);
foreach (var line in lines)
{
var parts = line.Split(new[] { " - " }, 2, StringSplitOptions.None);
if (parts.Length == 2)
{
_logEntries.Add(new LogEntry { Time = parts[0], Message = parts[1] });
}
}
// 更新 ListView
lvLogs.ItemsSource = null;
lvLogs.ItemsSource = _logEntries;
// 滚动到最后一条
if (_logEntries.Count > 0)
{
lvLogs.ScrollIntoView(_logEntries[_logEntries.Count - 1]);
}
}
private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
double totalWidth = lvLogs.ActualWidth;
double timeColumnWidth = 120; // 时间列固定宽度
double minMessageWidth = 200; // 消息列的最小宽度
double newMessageWidth = Math.Max(minMessageWidth, totalWidth - timeColumnWidth - 40); // 计算新宽度
((GridView)lvLogs.View).Columns[1].Width = newMessageWidth;
}
private void MenuItem_CopyMessage_Click(object sender, RoutedEventArgs e)
{
if (lvLogs.SelectedItem is LogEntry logEntry)
{
if (!LicenseMana.mIsLicensed)
{
MessageBox.Show(Application.Current.MainWindow, "软件未注册,不能使用此功能。", "提示",
MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
Clipboard.SetText(logEntry.Message);
}
}
//-----------------------------------------------------------------------------
}
}