Files
zijiuqizonghejianyanyi/ParameterSettingsWindow.xaml.cs
GukSang.Jin 88a65233a7 更新
2026-03-16 19:10:33 +08:00

781 lines
26 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 Modbus.Device;
using System;
using System.Configuration;
using System.Net.Sockets;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using .Data;
namespace
{
public partial class ParameterSettingsWindow : Window
{
private MainWindow _mainWindow;
private MainWindow2 _mainWindow2;
private MainWindow3 _mainWindow3;
private MainWindow4 _mainWindow4;
private readonly DispatcherTimer _readTimer;
private bool _isManualInput = false; // 手动输入标记true=输入中暂停读取false=正常读取
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
Function ma;
DataChange c = new DataChange();
public ParameterSettingsWindow()
{
InitializeComponent();
LoadCurrentSettings();
_readTimer = InitDispatcherTimer();
}
private DispatcherTimer InitDispatcherTimer()
{
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(500)
};
timer.Tick += async (s, e) =>
{
if (!_isManualInput && _modbusMaster != null)
{
try
{
await ReadAllPlcDataAsync();
}
catch { }
}
};
return timer;
}
private async System.Threading.Tasks.Task ReadAllPlcDataAsync()
{
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
return;
}
// 仅在非手动输入时读取设置地址(避免覆盖输入)
if (!_isManualInput)
{
await ReadAddr262DataAsync();
//await System.Threading.Tasks.Task.Delay(50);
//await ReadAddr404DataAsync();
//await System.Threading.Tasks.Task.Delay(50);
//await ReadAddr406DataAsync();
//await System.Threading.Tasks.Task.Delay(50);
//await ReadAddr130DataAsync();
}
}
// 加载当前设置
private void LoadCurrentSettings()
{
// 这里可以连接实际的数据源来加载当前设置
// 目前使用默认值
}
// 保存按钮点击事件
//private void SaveButton_Click(object sender, RoutedEventArgs e)
//{
// try
// {
// // 验证并保存所有参数
// if (ValidateParameters())
// {
// SaveParameters();
// MessageBox.Show("参数保存成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
// }
// }
// catch (Exception ex)
// {
// MessageBox.Show($"保存参数时出错:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
// }
//}
// 重置按钮点击事件
private void ResetButton_Click(object sender, RoutedEventArgs e)
{
var result = MessageBox.Show("确定要重置所有参数吗?", "确认重置",
MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
ResetToDefaults();
}
}
// 返回按钮点击事件
private void ReturnButton_Click(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow, () => new MainWindow());
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
// 1. 停止当前窗口的定时器(不释放资源)
_readTimer?.Stop();
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
{
WindowNavigationHelper.RestoreWindow(this, () => _readTimer?.Start());
};
}
else
{
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
return;
}
WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance);
}
// 添加重连方法
private bool TryReconnect()
{
try
{
string plcIp = "192.168.1.10";
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
if (initSuccess)
{
ma = new Function(_modbusMaster);
return true;
}
}
catch (Exception ex)
{
ShowErrorMsg($"重新连接失败:{ex.Message}");
}
return false;
}
private async System.Threading.Tasks.Task ReadAddr262DataAsync()
{
try
{
ushort[] registers3 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 1428, 2)
);
if (registers3 != null)
{
float addr406Value = c.UshortToFloat(registers3[1], registers3[0]);
Dispatcher.Invoke(() => txtPressureDiffCoefficient.Text = addr406Value.ToString("F2"));
}
ushort[] registers4 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 484, 2)
);
if (registers4 != null)
{
float addr406Value = c.UshortToFloat(registers4[1], registers4[0]);
Dispatcher.Invoke(() => txtUpperLimit.Text = addr406Value.ToString("F2"));
}
ushort[] registers5 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 482, 2)
);
if (registers5 != null)
{
float addr406Value = c.UshortToFloat(registers5[1], registers5[0]);
Dispatcher.Invoke(() => txtLowerLimit.Text = addr406Value.ToString("F2"));
}
ushort[] registers6 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 490, 2)
);
if (registers6 != null)
{
float addr406Value = c.UshortToFloat(registers6[1], registers6[0]);
Dispatcher.Invoke(() => txtLargeFlowCoefficient2.Text = addr406Value.ToString("F2"));
}
ushort[] registers7 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 492, 2)
);
if (registers7 != null)
{
float addr406Value = c.UshortToFloat(registers7[1], registers7[0]);
Dispatcher.Invoke(() => txtSmallFlowCoefficient2.Text = addr406Value.ToString("F2"));
}
ushort[] registers8 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 1328, 2)
);
if (registers8 != null)
{
float addr406Value = c.UshortToFloat(registers8[1], registers8[0]);
Dispatcher.Invoke(() => txtLargeFlowCoefficient.Text = addr406Value.ToString("F2"));
}
ushort[] registers9 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 1378, 2)
);
if (registers9 != null)
{
float addr406Value = c.UshortToFloat(registers9[1], registers9[0]);
Dispatcher.Invoke(() => txtSmallFlowCoefficient.Text = addr406Value.ToString("F2"));
}
ushort[] registers10 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 308, 2)
);
if (registers10 != null)
{
float addr406Value = c.UshortToFloat(registers10[1], registers10[0]);
Dispatcher.Invoke(() => txtQualityThreshold.Text = addr406Value.ToString("F2"));
}
ushort[] registers11 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 330, 2)
);
if (registers11 != null)
{
int addr406Value = registers11[0];
Dispatcher.Invoke(() => txtExhaustTime.Text = addr406Value.ToString("F0"));
}
ushort[] registers12 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 326, 1)
);
if (registers12 != null)
{
//float addr406Value = c.UshortToFloat(registers12[1], registers12[0]);
int addr406Value = registers12[0];
Dispatcher.Invoke(() => txtPositiveError.Text = addr406Value.ToString("F0"));
}
ushort[] registers13 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 316, 1)
);
if (registers13 != null)
{
//float addr406Value = c.UshortToFloat(registers13[1], registers13[0]);
float addr406Value = registers13[0];
Dispatcher.Invoke(() => txtNegativeError.Text = addr406Value.ToString("F0"));
}
ushort[] registers14 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 324, 1)
);
if (registers14 != null)
{
int addr406Value = registers14[0];
Dispatcher.Invoke(() => txtPositivePIDTime.Text = addr406Value.ToString("F0"));
}
ushort[] registers15 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 314, 1)
);
if (registers15 != null)
{
int addr406Value = registers15[0];
Dispatcher.Invoke(() => txtNegativePIDTime.Text = addr406Value.ToString("F0"));
}
ushort[] registers16 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 328, 1)
);
if (registers16 != null)
{
int addr406Value = registers16[0];
Dispatcher.Invoke(() => txtPositiveDelay.Text = addr406Value.ToString("F0"));
}
ushort[] registers17 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 318, 1)
);
if (registers17 != null)
{
int addr406Value = registers17[0];
Dispatcher.Invoke(() => txtNegativeDelay.Text = addr406Value.ToString("F0"));
}
ushort[] registers18 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 292, 2)
);
if (registers18 != null)
{
float addr406Value = c.UshortToFloat(registers18[1], registers18[0]);
Dispatcher.Invoke(() => txtPositivePIDPressure.Text = addr406Value.ToString("F2"));
}
ushort[] registers19 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 290, 2)
);
if (registers19 != null)
{
float addr406Value = c.UshortToFloat(registers19[1], registers19[0]);
Dispatcher.Invoke(() => txtNegativePIDPressure.Text = addr406Value.ToString("F2"));
}
ushort[] registers20 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 1430, 2)
);
if (registers20 != null)
{
float addr406Value = c.UshortToFloat(registers20[1], registers20[0]);
Dispatcher.Invoke(() => pressureDiff.Text = addr406Value.ToString("F2"));
}
ushort[] registers21 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 1330, 2)
);
if (registers21 != null)
{
float addr406Value = c.UshortToFloat(registers21[1], registers21[0]);
Dispatcher.Invoke(() => flow.Text = addr406Value.ToString("F2"));
}
// ushort[] registers22 = await System.Threading.Tasks.Task.Run(() =>
//_modbusMaster?.ReadHoldingRegisters(1, 390, 2)
//);
// if (registers22 != null)
// {
// int addr406Value = registers22[0];
// Dispatcher.Invoke(() => setsound.Text = addr406Value.ToString("F0"));
// }
}
catch (Exception ex)
{
//ShowErrorMsg($"读取地址406失败{ex.Message}");
}
}
private void ShowErrorMsg(string msg)
{
Dispatcher.Invoke(() =>
{
MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
});
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string plcIp = "192.168.1.10";
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
if (!initSuccess)
{
MessageBox.Show("连接Modbus服务器失败", "错误");
this.Close();
return;
}
// 检查连接状态
if (_tcpClient == null || !_tcpClient.Connected)
{
MessageBox.Show("Modbus连接异常", "错误");
this.Close();
return;
}
ma = new Function(_modbusMaster);
//ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 64);
System.Threading.Tasks.Task.Delay(50);
_readTimer.Start();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// 停止定时器
_readTimer?.Stop();
// 停止ViewModel的定时器
if (DataContext is MainViewModel viewModel)
{
viewModel.StopTimer();
}
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 延后到当前窗口完成关闭后再统一关停,避免关闭重入。
AppShutdownCoordinator.RequestShutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 由应用级关停统一处理其他窗口,避免关闭链路重入。
}
// 重置为默认值
private void ResetToDefaults()
{
txtPressureDiffCoefficient.Text = "0.00";
txtUpperLimit.Text = "0.0";
txtLowerLimit.Text = "0.0";
txtLargeFlowCoefficient.Text = "0.00";
txtSmallFlowCoefficient.Text = "0.00";
//txtYear.Text = "0";
//txtMonth.Text = "0";
//txtDay.Text = "0";
//txtHour.Text = "0";
//txtMinute.Text = "0";
//txtSecond.Text = "0";
txtQualityThreshold.Text = "0.00";
txtExhaustTime.Text = "0";
txtPositiveError.Text = "0";
txtNegativeError.Text = "0";
txtPositivePIDTime.Text = "0";
txtNegativePIDTime.Text = "0";
txtPositiveDelay.Text = "0";
txtNegativeDelay.Text = "0";
txtPositivePIDPressure.Text = "0.00";
txtNegativePIDPressure.Text = "0.00";
}
private void txtPressureDiffCoefficient_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
{
ma.WriteToPLCForNew(txtPressureDiffCoefficient.Text.Trim(), 1428, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ma.BtnClickFunctionForNew(Function.ButtonType., 1301);
}
private void txtLargeFlowCoefficient2_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtLargeFlowCoefficient2.Text.Trim(), 490, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtSmallFlowCoefficient2_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtSmallFlowCoefficient2.Text.Trim(), 492, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtPressureDiffCoefficient_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtPressureDiffCoefficient.Text.Trim(), 1428, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtUpperLimit_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtUpperLimit.Text.Trim(), 484, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtLowerLimit_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtLowerLimit.Text.Trim(), 482, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtLargeFlowCoefficient_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtLargeFlowCoefficient.Text.Trim(), 1328, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtSmallFlowCoefficient_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtSmallFlowCoefficient.Text.Trim(), 1378, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
ma.BtnClickFunctionForNew(Function.ButtonType., 1300);
}
private void txtQualityThreshold_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtQualityThreshold.Text.Trim(), 308, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtExhaustTime_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtExhaustTime.Text.Trim(), 330, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtPositiveError_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtPositiveError.Text.Trim(), 326, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
//private async void Button_Click_2(object sender, RoutedEventArgs e)
//{
// ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 24);
// bool[] b = await _modbusMaster.ReadCoilsAsync(1, 24, 1);
// if (b != null && b.Length > 0)
// {
// if (!b[0])
// {
// closesound.Content = "关闭语音";
// }
// else
// {
// closesound.Content = "开启语音";
// }
// }
//}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
ma.BtnClickFunctionForNew(Function.ButtonType., 25);
}
//private void setsound_GotFocus(object sender, RoutedEventArgs e)
//{
// ma.WriteToPLCForNew(setsound.Text.Trim(), 390, Function.DataType.整形);
// System.Threading.Tasks.Task.Delay(50);
// _isManualInput = false; // 写入后恢复读取
// t0.Focus();
//}
private void txtNegativeError_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtNegativeError.Text.Trim(), 316, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtPositivePIDTime_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtPositivePIDTime.Text.Trim(), 324, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtNegativePIDTime_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtNegativePIDTime.Text.Trim(), 314, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtPositiveDelay_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtPositiveDelay.Text.Trim(), 328, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtNegativeDelay_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtNegativeDelay.Text.Trim(), 318, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtPositivePIDPressure_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtPositivePIDPressure.Text.Trim(), 292, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
private void txtNegativePIDPressure_GotFocus(object sender, RoutedEventArgs e)
{
ma.WriteToPLCForNew(txtNegativePIDPressure.Text.Trim(), 290, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
t0.Focus();
}
//private void pressureDiff2_GotFocus(object sender, RoutedEventArgs e)
//{
//}
/// <summary>
/// 保存 AppSettings 配置到配置文件
/// </summary>
/// <param name="key">配置键名</param>
/// <param name="value">配置值</param>
/// <returns>是否保存成功</returns>
public bool SaveAppSetting(string key, string value)
{
try
{
// 1. 获取当前程序的配置文件路径(编译后的 exe.config
string configPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
// 2. 加载配置文件ExeConfigurationFileMap 指定配置路径)
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap { ExeConfigFilename = configPath };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
// 3. 处理 appSettings 节点
if (config.AppSettings.Settings[key] == null)
{
// 键不存在 → 新增配置
config.AppSettings.Settings.Add(key, value);
}
else
{
// 键已存在 → 更新配置
config.AppSettings.Settings[key].Value = value;
}
// 4. 保存配置(重要!否则修改不生效)
config.Save(ConfigurationSaveMode.Modified);
// 5. 刷新 ConfigurationManager 缓存(可选,让后续读取能立即获取新值)
ConfigurationManager.RefreshSection("appSettings");
return true;
}
catch (Exception ex)
{
// 捕获异常(如权限不足、文件被占用等)
MessageBox.Show($"保存配置失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
}
}
}