Files
zijiuqizonghejianyanyi/MainWindow4.xaml.cs
2026-03-16 15:36:54 +08:00

577 lines
20 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 Modbus.Device;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
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 System.Windows.Threading;
using System.Windows.Media.Animation;
using ;
using .Data;
namespace
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow4 : Window
{
private MainWindow _mainWindow;
private MainWindow2 _mainWindow2;
private MainWindow3 _mainWindow3;
private MainWindow4 _mainWindow4;
private ReportWindow4 _reportWindow4;
private bool _wasRunning = false; // 上次检验的运行状态
private bool _recordAdded = false; // 本轮测试是否已插入记录
private DateTime _testStartTime; // 测试开始时间
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
private const byte SlaveId = 1; // PLC从站地址
private const ushort Address262 = 262; // 32位浮点数float32占2个寄存器
private const ushort Address2506 = 2506; // 32位浮点数float32占2个寄存器
private const ushort Address2502 = 2502; // 32位浮点数float32占2个寄存器
// Modbus通信
private bool _isManualInput = false; // 手动输入标记true=输入中暂停读取false=正常读取
private readonly DispatcherTimer _readTimer;
Function ma;
DataChange c = new DataChange();
public MainWindow4()
{
InitializeComponent();
_readTimer = InitDispatcherTimer();
//InitializeModbusTcp();
BindInputFocusEvents();
}
private void BindInputFocusEvents()
{
// 地址400输入框count
//settingtime.GotFocus += (s, e) => _isManualInput = true; // 获得焦点→暂停读取
//settingtime.LostFocus += (s, e) => _isManualInput = false; // 失去焦点→恢复读取
//// 地址404输入框count2
//count2.GotFocus += (s, e) => _isManualInput = true;
//count2.LostFocus += (s, e) => _isManualInput = false;
//// 地址406输入框count3
//count3.GotFocus += (s, e) => _isManualInput = true;
//count3.LostFocus += (s, e) => _isManualInput = false;
}
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 void InitializeModbusTcp()
//{
// try
// {
// // 从配置读取PLC连接信息
// string plcIp = "192.168.1.10";
// int plcPort = 502;
// _tcpClient = new TcpClient(plcIp, plcPort);
// _modbusMaster = ModbusIpMaster.CreateIp(_tcpClient);
// _modbusMaster.Transport.ReadTimeout = 3000;
// _modbusMaster.Transport.WriteTimeout = 3000;
// // 初始化定时器
// //InitializeTimers();
// // 初始化数据库
// //InitializeDatabase();
// _readTimer.Start();
// ma = new Function(_modbusMaster);
// }
// catch (Exception ex)
// {
// ShowErrorMsg($"Modbus初始化失败: {ex.Message}");
// }
//}
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();
}
await ReadAddrStatusDataAsync();
}
private async System.Threading.Tasks.Task ReadAddr262DataAsync()
{
try
{
ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster.ReadHoldingRegisters(1, 1430, 2)
);
if (registers != null)
{
float addr406Value = c.UshortToFloat(registers[1], registers[0]);
Dispatcher.Invoke(() => settingtime.Text = addr406Value.ToString("F2"));
}
}
catch (Exception ex)
{
//ShowErrorMsg($"读取地址406失败{ex.Message}");
}
}
private async System.Threading.Tasks.Task ReadAddr404DataAsync()
{
try
{
ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster.ReadHoldingRegisters(1, 106, 2)
);
if (registers != null)
{
float addr406Value = c.UshortToFloat(registers[1], registers[0]);
Dispatcher.Invoke(() => settingtime2.Text = addr406Value.ToString("F2"));
}
}
catch (Exception ex)
{
//ShowErrorMsg($"读取地址406失败{ex.Message}");
}
}
private void ShowErrorMsg(string msg)
{
Dispatcher.Invoke(() =>
{
MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
});
}
private void Button_Click(object sender, RoutedEventArgs e)
{
OpenQuantitativeSupplyWindow4();
}
private void OpenQuantitativeSupplyWindow4()
{
try
{
SwitchWindow(ref _reportWindow4, () => new ReportWindow4());
}
catch (Exception ex)
{
MessageBox.Show($"打开定量供应检验窗口时出错:{ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
ma.BtnClickFunctionForNew(Function.ButtonType., 100);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
//ma.BtnClickFunctionForNew(Function.ButtonType.复归型, 103);
ma.BtnClickFunctionForNew(Function.ButtonType., 103);
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
ma.BtnClickFunctionForNew(Function.ButtonType., 15);
}
private void Button_Click_4(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow, () => new MainWindow());
}
private void Button_Click_5(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow2, () => new MainWindow2());
}
private void Button_Click_6(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow3, () => new MainWindow3());
}
private void Button_Click_7(object sender, RoutedEventArgs e)
{
SwitchWindow(ref _mainWindow4, () => new MainWindow4());
}
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();
_modbusMaster.WriteSingleCoil(1, 61, false);
System.Threading.Tasks.Task.Delay(50);
_modbusMaster.WriteSingleCoil(1, 62, false);
System.Threading.Tasks.Task.Delay(50);
_modbusMaster.WriteSingleCoil(1, 63, false);
System.Threading.Tasks.Task.Delay(50);
_modbusMaster.WriteSingleCoil(1, 64, true);
System.Threading.Tasks.Task.Delay(50);
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
{
_readTimer?.Stop();
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
if (!TryReconnect())
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
Window overlay = null;
try
{
overlay = new Window
{
Owner = this,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = Brushes.Transparent,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Width = this.ActualWidth,
Height = this.ActualHeight,
Left = this.Left,
Top = this.Top,
ShowActivated = false,
Topmost = true
};
var grid = new Grid();
var tb = new TextBlock
{
Text = "正在加载,请稍候...",
Foreground = Brushes.Black,
Background = Brushes.Transparent,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom,
Margin = new Thickness(0, 0, 0, 20),
FontSize = 16
};
grid.Children.Add(tb);
overlay.Content = grid;
overlay.Show();
void ShowTargetWindow(T target)
{
if (target.IsVisible)
{
target.Activate();
this.Hide();
overlay?.Close();
return;
}
target.Opacity = 0;
void OnContentRendered(object s, EventArgs e)
{
target.ContentRendered -= OnContentRendered;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
target.BeginAnimation(Window.OpacityProperty, anim);
this.Hide();
target.Activate();
overlay?.Close();
}
target.ContentRendered += OnContentRendered;
target.Show();
}
if (windowInstance == null)
{
windowInstance = createFunc();
windowInstance.Closed += (s, args) =>
{
_readTimer?.Start();
this.Activate();
};
ShowTargetWindow(windowInstance);
}
else
{
ShowTargetWindow(windowInstance);
}
}
catch (Exception ex)
{
overlay?.Close();
ShowErrorMsg($"切换窗口失败:{ex.Message}");
}
}
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 void BtnWrite401_Click(object sender, RoutedEventArgs e)
{
if (!double.TryParse(settingtime.Text.Trim(), out double writeValue) ||
writeValue > short.MaxValue)
{
ShowErrorMsg($"需输入整数(范围:{short.MinValue} ~ {short.MaxValue}");
settingtime.Focus();
return;
}
try
{
//await System.Threading.Tasks.Task.Run(() =>
// _modbusMaster.WriteSingleRegister(SlaveId, Address262, (ushort)writeValue)
//);
ma.WriteToPLCForNew(settingtime.Text.Trim(), 1430, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
//await ReadAddr400DataAsync(); // 刷新显示(确认写入成功)
}
catch (Exception ex)
{
//ShowErrorMsg($"地址400写入失败{ex.Message}");
}
}
private void BtnWrite402_Click(object sender, RoutedEventArgs e)
{
if (!double.TryParse(settingtime2.Text.Trim(), out double writeValue) ||
writeValue > short.MaxValue)
{
ShowErrorMsg($"需输入整数(范围:{short.MinValue} ~ {short.MaxValue}");
settingtime.Focus();
return;
}
try
{
//await System.Threading.Tasks.Task.Run(() =>
// _modbusMaster.WriteSingleRegister(SlaveId, Address262, (ushort)writeValue)
//);
ma.WriteToPLCForNew(settingtime2.Text.Trim(), 106, Function.DataType.);
System.Threading.Tasks.Task.Delay(50);
_isManualInput = false; // 写入后恢复读取
//await ReadAddr400DataAsync(); // 刷新显示(确认写入成功)
}
catch (Exception ex)
{
//ShowErrorMsg($"地址400写入失败{ex.Message}");
}
}
private async System.Threading.Tasks.Task ReadAddrStatusDataAsync()
{
try
{
bool[] result = _modbusMaster?.ReadCoils(0x01, 101, 1);
bool isTestRunning = result != null && result.Length > 0 && result[0];
Dispatcher.Invoke(() =>
{
if (isTestRunning)
{
status.Text = "正在运行";
statusPanel.Background = Brushes.Green;
if (!_wasRunning)
{
_testStartTime = DateTime.Now;
_recordAdded = false; // 测试刚开始,允许插入记录
}
}
else
{
status.Text = "空闲";
statusPanel.Background = Brushes.Blue;
// 状态从“运行”切换到“空闲”,且还没插入记录
if (_wasRunning && !_recordAdded)
{
AddTestRecord(); // 插入记录
_recordAdded = true; // 标记已插入
}
}
_wasRunning = isTestRunning; // 更新上一次状态
});
}
catch (Exception ex)
{
ShowErrorMsg($"读取运行状态失败:{ex.Message}");
}
}
private void AddTestRecord()
{
try
{
// 计算测试时长
TimeSpan duration = DateTime.Now - _testStartTime;
string durationStr = $"{duration.Minutes:00}:{duration.Seconds:00}";
// 获取当前流量值
double currentFlowRate = 0;
if (!string.IsNullOrEmpty(settingtime2.Text) && double.TryParse(settingtime2.Text, out double flow))
{
currentFlowRate = flow;
}
// 获取当前时间
string currentTime = DateTime.Now.ToString("HH:mm");
string currentDate = DateTime.Now.ToString("yy/MM/dd");
// 添加到报表窗口(如果存在或创建)
Dispatcher.Invoke(() =>
{
// 如果窗口不存在,先创建但不显示
if (_reportWindow4 == null)
{
_reportWindow4 = new ReportWindow4();
}
string no = ConfigurationManager.AppSettings["No"]?.ToString();
// 添加记录到窗口(无论窗口是否显示)
_reportWindow4.AddRecord(currentTime, currentDate, currentFlowRate, durationStr, no);
});
}
catch (Exception ex)
{
ShowErrorMsg($"记录测试数据失败:{ex.Message}");
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// 停止定时器
_readTimer?.Stop();
// 停止ViewModel的定时器
if (DataContext is MainViewModel viewModel)
{
viewModel.StopTimer();
}
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 确保应用程序完全退出
Application.Current.Shutdown();
}
private void Window_Closed(object sender, EventArgs e)
{
// 清理其他窗口实例
_mainWindow2?.Close();
_mainWindow3?.Close();
//_mainWindow4?.Close();
_mainWindow?.Close();
_reportWindow4?.Close();
}
}
}