263 lines
11 KiB
C#
263 lines
11 KiB
C#
|
|
using Microsoft.Win32;
|
|||
|
|
using Modbus.Device;
|
|||
|
|
using System;
|
|||
|
|
using System.Configuration;
|
|||
|
|
using System.Diagnostics;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Net.Sockets;
|
|||
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Controls;
|
|||
|
|
using System.Windows.Documents;
|
|||
|
|
using 软胶囊弹性硬度测试仪.Data;
|
|||
|
|
|
|||
|
|
namespace EmptyLoadTest
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
public partial class ExperimentReportWindow : Window
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
|
|||
|
|
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
// 2. 改为公共可读写属性(核心:外部可直接修改)
|
|||
|
|
public ExperimentReportData ReportData { get; set; }
|
|||
|
|
|
|||
|
|
|
|||
|
|
// 无参构造(方便单例创建,默认初始化空数据)
|
|||
|
|
public ExperimentReportWindow()
|
|||
|
|
{
|
|||
|
|
InitializeComponent();
|
|||
|
|
ReportData = new ExperimentReportData();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 简化的导出方法 - 只导出为文本和CSV格式
|
|||
|
|
private void ExportReport_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
SaveFileDialog saveFileDialog = new SaveFileDialog
|
|||
|
|
{
|
|||
|
|
Filter = "CSV文件 (*.csv)|*.csv",
|
|||
|
|
FileName = $"实验报告_{DateTime.Now:yyyyMMdd_HHmmss}",
|
|||
|
|
DefaultExt = ".csv",
|
|||
|
|
Title = "保存实验报告"
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (saveFileDialog.ShowDialog() == true)
|
|||
|
|
{
|
|||
|
|
string filePath = saveFileDialog.FileName;
|
|||
|
|
string fileExt = Path.GetExtension(filePath).ToLower();
|
|||
|
|
|
|||
|
|
if (fileExt == ".csv")
|
|||
|
|
{
|
|||
|
|
ExportToCsvFile(filePath);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var result = MessageBox.Show("报告导出成功!\n是否要打开文件?",
|
|||
|
|
"导出成功", MessageBoxButton.YesNo, MessageBoxImage.Information);
|
|||
|
|
|
|||
|
|
if (result == MessageBoxResult.Yes)
|
|||
|
|
{
|
|||
|
|
Process.Start(new ProcessStartInfo(filePath) { UseShellExecute = true });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show($"导出失败:{ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 导出为CSV文件
|
|||
|
|
private void ExportToCsvFile(string filePath)
|
|||
|
|
{
|
|||
|
|
using (StreamWriter writer = new StreamWriter(filePath, false, System.Text.Encoding.UTF8))
|
|||
|
|
{
|
|||
|
|
writer.WriteLine("项目,数值,单位");
|
|||
|
|
writer.WriteLine($"设置转速,{ReportData.SetSpeed:F1},转/分钟");
|
|||
|
|
writer.WriteLine($"实际转速1,{ReportData.ActualSpeed1:F1},转/分钟");
|
|||
|
|
writer.WriteLine($"实际转速2,{ReportData.ActualSpeed2:F1},转/分钟");
|
|||
|
|
writer.WriteLine($"实际转速3,{ReportData.ActualSpeed3:F1},转/分钟");
|
|||
|
|
writer.WriteLine($"设置往复频率,{ReportData.SetFrequency:F0},次/分钟");
|
|||
|
|
writer.WriteLine($"实际往复频率1,{ReportData.ActualFrequency1:F0},次/分钟");
|
|||
|
|
writer.WriteLine($"实际往复频率2,{ReportData.ActualFrequency2:F0},次/分钟");
|
|||
|
|
writer.WriteLine($"实际往复频率3,{ReportData.ActualFrequency3:F0},次/分钟");
|
|||
|
|
writer.WriteLine($"设置额定扭矩,{ReportData.SetTorque:F1},N.cm");
|
|||
|
|
writer.WriteLine($"测试时间,{ReportData.TestTime},秒");
|
|||
|
|
writer.WriteLine($"到达设定扭矩时的转速,{ReportData.SpeedAtSetTorque:F0},转/分钟");
|
|||
|
|
writer.WriteLine($"最大扭矩时的转速,{ReportData.SpeedAtMaxTorque:F0},转/分钟");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 简化的打印预览
|
|||
|
|
private void PrintPreview_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
PrintDialog printDialog = new PrintDialog();
|
|||
|
|
|
|||
|
|
// 创建简单的打印文档
|
|||
|
|
FlowDocument doc = new FlowDocument();
|
|||
|
|
doc.Blocks.Add(new Paragraph(new Run("实验报告")));
|
|||
|
|
doc.Blocks.Add(new Paragraph(new Run("")));
|
|||
|
|
doc.Blocks.Add(new Paragraph(new Run($"样品编号:{ReportData.SampleId}")));
|
|||
|
|
doc.Blocks.Add(new Paragraph(new Run($"测试日期:{ReportData.TestDate:yyyy年MM月dd日}")));
|
|||
|
|
|
|||
|
|
if (printDialog.ShowDialog() == true)
|
|||
|
|
{
|
|||
|
|
printDialog.PrintDocument(((IDocumentPaginatorSource)doc).DocumentPaginator, "实验报告");
|
|||
|
|
MessageBox.Show("打印作业已发送到打印机。", "打印成功");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show($"打印失败:{ex.Message}", "错误");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 打开文件夹按钮点击事件
|
|||
|
|
private void OpenFolder_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
System.Diagnostics.Process.Start("explorer.exe", @"C:\");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show($"打开文件夹失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// 返回按钮点击事件
|
|||
|
|
private void Return_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
var mainWindow = MainWindow.Instance;
|
|||
|
|
|
|||
|
|
if (!mainWindow.IsVisible)
|
|||
|
|
{
|
|||
|
|
mainWindow.Show();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
mainWindow.Activate();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Close();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. 修正单例逻辑:确保单例的 ReportData 可被外部修改,不丢失数据
|
|||
|
|
private static ExperimentReportWindow _instance;
|
|||
|
|
// 加锁保证线程安全
|
|||
|
|
private static readonly object _lock = new object();
|
|||
|
|
public static ExperimentReportWindow Instance
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
lock (_lock)
|
|||
|
|
{
|
|||
|
|
if (_instance == null || !_instance.IsLoaded)
|
|||
|
|
{
|
|||
|
|
_instance = new ExperimentReportWindow(); // 使用无参构造,初始化空数据
|
|||
|
|
}
|
|||
|
|
return _instance;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. 修正单例逻辑:确保单例的 ReportData 可被外部修改,不丢失数据
|
|||
|
|
private static TorqueParameterWindow _instance2;
|
|||
|
|
// 加锁保证线程安全
|
|||
|
|
private static readonly object _lock2 = new object();
|
|||
|
|
public static TorqueParameterWindow Instance2
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
lock (_lock2)
|
|||
|
|
{
|
|||
|
|
if (_instance2 == null || !_instance2.IsLoaded)
|
|||
|
|
{
|
|||
|
|
_instance2 = new TorqueParameterWindow(); // 使用无参构造,初始化空数据
|
|||
|
|
}
|
|||
|
|
return _instance2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
|||
|
|
|
|||
|
|
ReportData.SetSpeed = double.Parse(config.AppSettings.Settings["SettingSpeed"].Value);
|
|||
|
|
ReportData.ActualSpeed1 = double.Parse(config.AppSettings.Settings["ActualSpeed1"].Value);
|
|||
|
|
ReportData.ActualSpeed2 = double.Parse(config.AppSettings.Settings["ActualSpeed2"].Value);
|
|||
|
|
ReportData.ActualSpeed3 = double.Parse(config.AppSettings.Settings["ActualSpeed3"].Value);
|
|||
|
|
|
|||
|
|
|
|||
|
|
ReportData.SetFrequency = double.Parse(config.AppSettings.Settings["interval"].Value);
|
|||
|
|
ReportData.ActualFrequency1 = double.Parse(config.AppSettings.Settings["interval1"].Value);
|
|||
|
|
ReportData.ActualFrequency2 = double.Parse(config.AppSettings.Settings["interval2"].Value);
|
|||
|
|
ReportData.ActualFrequency3 = double.Parse(config.AppSettings.Settings["interval3"].Value);
|
|||
|
|
|
|||
|
|
|
|||
|
|
txtSetSpeed.Text = ReportData.SetSpeed.ToString();
|
|||
|
|
txtActualSpeed1.Text = ReportData.ActualSpeed1.ToString();
|
|||
|
|
txtActualSpeed2.Text = ReportData.ActualSpeed2.ToString();
|
|||
|
|
txtActualSpeed3.Text = ReportData.ActualSpeed3.ToString();
|
|||
|
|
txtSetFrequency.Text = ReportData.SetFrequency.ToString();
|
|||
|
|
txtActualFrequency1.Text = ReportData.ActualFrequency1.ToString();
|
|||
|
|
txtActualFrequency2.Text = ReportData.ActualFrequency2.ToString();
|
|||
|
|
txtActualFrequency3.Text = ReportData.ActualFrequency3.ToString();
|
|||
|
|
|
|||
|
|
|
|||
|
|
ReportData.SetTorque = double.Parse(config.AppSettings.Settings["txtSetTorque"].Value);
|
|||
|
|
ReportData.TestTime = float.Parse(config.AppSettings.Settings["txtTestTime"].Value);
|
|||
|
|
ReportData.SpeedAtSetTorque = double.Parse(config.AppSettings.Settings["txtSpeedAtSetTorque"].Value);
|
|||
|
|
ReportData.SpeedAtMaxTorque = double.Parse(config.AppSettings.Settings["txtSpeedAtMaxTorque"].Value);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
txtSetTorque.Text = ReportData.SetTorque.ToString();
|
|||
|
|
txtTestTime.Text = ReportData.TestTime.ToString();
|
|||
|
|
txtSpeedAtSetTorque.Text = ReportData.SpeedAtSetTorque.ToString();
|
|||
|
|
txtSpeedAtMaxTorque.Text = ReportData.SpeedAtMaxTorque.ToString();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 1. 提取为独立类(外部可直接创建/修改,无需嵌套访问)
|
|||
|
|
public class ExperimentReportData
|
|||
|
|
{
|
|||
|
|
// 样品信息
|
|||
|
|
public string SampleId { get; set; } = "";
|
|||
|
|
public DateTime TestDate { get; set; } = DateTime.Today;
|
|||
|
|
public string Tester { get; set; } = "";
|
|||
|
|
public string DeviceId { get; set; } = "";
|
|||
|
|
|
|||
|
|
// 空载测试
|
|||
|
|
public double SetSpeed { get; set; } = 0;
|
|||
|
|
public double ActualSpeed1 { get; set; } = 0;
|
|||
|
|
public double ActualSpeed2 { get; set; } = 0;
|
|||
|
|
public double ActualSpeed3 { get; set; } = 0;
|
|||
|
|
public double SetFrequency { get; set; } = 0;
|
|||
|
|
public double ActualFrequency1 { get; set; } = 0;
|
|||
|
|
public double ActualFrequency2 { get; set; } = 0;
|
|||
|
|
public double ActualFrequency3 { get; set; } = 0;
|
|||
|
|
|
|||
|
|
// 负载测试
|
|||
|
|
public double SetTorque { get; set; } = 0;
|
|||
|
|
public float TestTime { get; set; } = 0;
|
|||
|
|
public double SpeedAtSetTorque { get; set; } = 0;
|
|||
|
|
public double SpeedAtMaxTorque { get; set; } = 0;
|
|||
|
|
|
|||
|
|
// 测试结论
|
|||
|
|
public string Conclusion { get; set; } =
|
|||
|
|
"空载测试:转速和往复频率均在允许误差范围内,设备运行正常。\n" +
|
|||
|
|
"负载测试:设备在额定扭矩下运行稳定,扭矩-转速曲线符合设计要求。\n" +
|
|||
|
|
"总体评价:测试合格,设备性能良好。";
|
|||
|
|
}
|