From abcf9da1db8888233d70b335ed1d4f61d6da866f Mon Sep 17 00:00:00 2001 From: xyy <544939200@qq.com> Date: Sun, 1 Feb 2026 19:14:07 +0800 Subject: [PATCH] --- 建材不燃性试验炉/MainWindow.xaml | 124 +++ 建材不燃性试验炉/MainWindow.xaml.cs | 1014 ++++++++++++++++++--- 建材不燃性试验炉/TestReportWindow.xaml | 72 +- 建材不燃性试验炉/TestReportWindow.xaml.cs | 236 ++++- 建材不燃性试验炉/data/ReportData.cs | 29 +- 建材不燃性试验炉/建材不燃性试验炉.csproj | 7 +- 6 files changed, 1278 insertions(+), 204 deletions(-) diff --git a/建材不燃性试验炉/MainWindow.xaml b/建材不燃性试验炉/MainWindow.xaml index 156ab6d..e4164c6 100644 --- a/建材不燃性试验炉/MainWindow.xaml +++ b/建材不燃性试验炉/MainWindow.xaml @@ -876,6 +876,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -966,6 +1081,15 @@ VerticalAlignment="Center"/> + + + + + + + + + _finalTempData; + private bool _isFinalBalanceChecking; + private double _finalInitialTemp; + private double _finalMaxTemp; + private double _finalFinalTemp; + private TimeSpan _finalBalanceStartTime; + #endregion + + + // Modbus相关 private TcpClient _tcpClient => Data.ModbusResourceManager.Instance?.TcpClient; private IModbusMaster _modbusMaster => Data.ModbusResourceManager.Instance?.ModbusMaster; @@ -61,16 +77,18 @@ namespace 建材不燃性试验炉 InitializeControls(); InitializeBalanceVariables();//温度平衡相关变量 + InitializeFinalBalance(); // 新增 + ResetFinalBalanceUI(); } - private void InitializeBalanceVariables() - { - _tempDataList = new List(); - _balanceTotalSeconds = 600; - _maxTempDiffThreshold = 10; - _tempRangeThreshold = 2; - _isBalanceChecking = false; - } + //private void InitializeBalanceVariables() + //{ + // _tempDataList = new List(); + // _balanceTotalSeconds = 600; + // _maxTempDiffThreshold = 10; + // _tempRangeThreshold = 2; + // _isBalanceChecking = false; + //} private void InitializeTimers() { @@ -142,7 +160,6 @@ namespace 建材不燃性试验炉 c = new DataChange(); ma = new Function(_modbusMaster); - // 启动状态定时器 _statusTimer.Start(); @@ -301,6 +318,8 @@ namespace 建材不燃性试验炉 txtProgress.Text = "0%"; UpdateStatusBar("试验开始"); + ResetFinalBalanceUI(); + StartFinalBalanceCheck(); } catch (Exception ex) { @@ -324,6 +343,7 @@ namespace 建材不燃性试验炉 btnStartBalanceCheck.IsEnabled = true; txtBalanceStatus.Text = "温度平衡状态: 已停止判断"; } + StopFinalBalanceCheck(); } private void StopTest() @@ -491,9 +511,9 @@ namespace 建材不燃性试验炉 if (Dispatcher.CheckAccess()) { txtFinalWeight.IsEnabled = true; - txtFinalWeight.Background = Brushes.White; + txtFinalWeight.Background = Brushes.White; txtFinalWeight.Text = ""; - + } else { @@ -524,8 +544,8 @@ namespace 建材不燃性试验炉 { // 实时更新重量计算 UpdateWeightCalculation(); - - } + + } private void UpdateWeightCalculation() { @@ -705,14 +725,14 @@ namespace 建材不燃性试验炉 #region 温度监控相关 //private void UpdateSimulatedTemperatures() //{ - + // // 试验中的温度模拟 // double furnaceWallTemp = 750 + (_random.NextDouble() * 10 - 5); // 750±5°C // double sampleCenterTemp = 500 + (_random.NextDouble() * 50 - 25); // 500±25°C // double sampleSurfaceTemp = 600 + (_random.NextDouble() * 40 - 20); // 600±20°C // UpdateTemperatureDisplay(furnaceWallTemp, sampleCenterTemp, sampleSurfaceTemp); - + //} private void UpdateSimulatedTemperatures() @@ -746,14 +766,14 @@ namespace 建材不燃性试验炉 // 样品内温度相关 (D1280) ReadAndUpdateRegister(1280, 2, value => { - sampleInternalTemp= value; + sampleInternalTemp = value; Dispatcher.Invoke(() => txtSampleCenterTemp.Text = $"{value:F1}°C"); }); // 样品外温度相关 (D1330) ReadAndUpdateRegister(1330, 2, value => { - sampleSurfaceTemp= value; + sampleSurfaceTemp = value; Dispatcher.Invoke(() => txtSampleSurfaceTemp.Text = $"{value:F1}°C"); }); @@ -934,7 +954,7 @@ namespace 建材不燃性试验炉 #region 系统状态更新 private void UpdateSystemStatus() { - + if (_tcpClient == null || _tcpClient.Connected) { txtStatusBar.Text = $"系统就绪 | {DateTime.Now:HH:mm:ss}"; @@ -997,8 +1017,8 @@ namespace 建材不燃性试验炉 } } - private void SetDeviceStatusUI(string statusText, string buttonText, Brush statusColor) - { + private void SetDeviceStatusUI(string statusText, string buttonText, Brush statusColor) + { try { // 检查UI控件是否为空 @@ -1032,7 +1052,7 @@ namespace 建材不燃性试验炉 { Debug.WriteLine($"更新UI状态时发生错误:{ex.Message}"); } - } + } #endregion @@ -1360,131 +1380,6 @@ namespace 建材不燃性试验炉 } #endregion - #region 温度平衡相关 - // 开始平衡判断按钮点击事件 - private void btnStartBalanceCheck_Click(object sender, RoutedEventArgs e) - { - - if (_isBalanceChecking) - { - MessageBox.Show("温度平衡判断正在进行中,请等待完成", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - return; - } - - try - { - // 1. 获取用户设置的参数 - if (!int.TryParse(txtBalanceTime.Text, out _balanceTotalSeconds) || _balanceTotalSeconds <= 0) - { - MessageBox.Show("请输入有效的平衡计时秒数(正数)", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - - if (!double.TryParse(txtMaxTempDiff.Text, out _maxTempDiffThreshold) || _maxTempDiffThreshold < 0) - { - MessageBox.Show("请输入有效的最大温差阈值(非负数)", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - - if (!double.TryParse(txtTempRange.Text, out _tempRangeThreshold) || _tempRangeThreshold < 0) - { - MessageBox.Show("请输入有效的温度范围阈值(非负数)", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - - // 2. 重置变量 - _balanceElapsedSeconds = 0; - _tempDataList.Clear(); - _maxTemp = double.MinValue; - _minTemp = double.MaxValue; - _avgTemp = 0; - _isBalanceChecking = true; - - // 3. 更新界面 - txtBalanceTimeElapsed.Text = $"0秒"; - txtBalanceStatus.Text = $"温度平衡状态: 正在判断"; - balanceStatusBorder.Background = new SolidColorBrush(Colors.Gray); - txtBalanceResult.Text = "判断中"; - UpdateStatusBar($"开始温度平衡判断,计时..."); - - // 4. 启动定时器 - _balanceTimer.Start(); - - // 5. 打开温度曲线图窗口 - OpenBalanceChartWindow(); - - } - catch (Exception ex) - { - MessageBox.Show($"启动平衡判断失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); - } - } - - private void OpenBalanceChartWindow() - { - try - { - // 创建温度获取函数 - Func getFurnaceTemperature = () => - { - try - { - // 从Modbus读取炉内温度 - if (_modbusMaster != null && _tcpClient != null && _tcpClient.Connected) - { - ushort[] registers = _modbusMaster.ReadHoldingRegisters(1, 1230, 2); - if (registers != null && registers.Length >= 2) - { - float temperature = c.UshortToFloat(registers[1], registers[0]); - return temperature; - } - } - return 0.0; - } - catch (Exception ex) - { - Debug.WriteLine($"获取炉内温度失败: {ex.Message}"); - return 0.0; - } - }; - - // 创建并显示温度曲线图窗口 - BalanceChartWindow chartWindow = new BalanceChartWindow(getFurnaceTemperature); - chartWindow.Owner = this; - chartWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; - chartWindow.Show(); - - UpdateStatusBar("打开温度平衡曲线图"); - } - catch (Exception ex) - { - MessageBox.Show($"无法打开温度曲线图: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); - } - } - - private void btnStopBalanceCheck_Click(object sender, RoutedEventArgs e) - { - if (!_isBalanceChecking) - { - MessageBox.Show("当前未进行温度平衡判断", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - return; - } - - // 1. 停止定时器 - _balanceTimer.Stop(); - - // 2. 重置状态 - _isBalanceChecking = false; - - - // 3. 更新界面提示 - txtBalanceStatus.Text = $"温度平衡状态: 已手动停止(已计时{_balanceElapsedSeconds}秒)"; - txtBalanceResult.Text = "已停止"; - balanceStatusBorder.Background = new SolidColorBrush(Colors.Orange); - UpdateStatusBar($"温度平衡判断已手动停止(已计时{_balanceElapsedSeconds}秒)"); - } - #endregion - #region 辅助方法 private void UpdateStatusBar(string message) { @@ -1579,6 +1474,16 @@ namespace 建材不燃性试验炉 if (windowInstance == null) { windowInstance = createFunc(); + + + + + if (windowInstance is TestReportWindow reportWindow) + { + + } + + // 添加窗口关闭事件处理 windowInstance.Closed += (s, args) => { @@ -1597,7 +1502,7 @@ namespace 建材不燃性试验炉 // 3. 切换窗口:隐藏当前窗口,显示目标窗口(非模态) this.Hide(); - windowInstance.Show(); + windowInstance.Show(); } @@ -1605,6 +1510,819 @@ namespace 建材不燃性试验炉 #endregion - + + + #region 温度平衡相关 + // 开始平衡判断按钮点击事件 + + private void btnStartBalanceCheck_Click(object sender, RoutedEventArgs e) + { + if (_isBalanceChecking) + { + MessageBox.Show("温度平衡判断正在进行中,请等待完成", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + return; + } + + try + { + // 1. 初始化平衡判断变量 + InitializeBalanceVariables(); + + // 2. 重置UI状态 + ResetBalanceUI(); + + // 3. 开始平衡判断 + StartBalanceCheck(); + + // 4. 打开平衡曲线图 + //OpenBalanceChartWindow(); + + UpdateStatusBar("开始温度平衡判断,严格按照GB/T 5464-2010标准执行"); + } + catch (Exception ex) + { + MessageBox.Show($"启动平衡判断失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); + ResetBalanceUI(); + } + } + + #region 温度平衡核心方法 + private void InitializeBalanceVariables() + { + // 标准7.2.4:平衡时间为10分钟 + _balanceTotalSeconds = 600; // 600秒 = 10分钟 + _balanceElapsedSeconds = 0; + + // 标准参数:温度平均值750±5℃,最大偏差10℃,漂移2℃ + _maxTempDiffThreshold = 10; // 10℃(标准7.2.4:相对平均温度的最大偏差不超过10℃) + _tempRangeThreshold = 2; // 2℃(标准7.2.4:温度漂移不超过2℃) + _targetTemperature = 750; // 标准目标温度 + + _tempDataList = new List(); + // 清空数据列表 + _tempDataList?.Clear(); + + // 平衡统计变量 + _isBalanceChecking = false; + _balanceStatistics = new BalanceStatistics(); + } + + private void ResetBalanceUI() + { + txtBalanceTimeElapsed.Text = "0秒"; + txtBalanceCondition.Text = "平衡条件: 炉温(750±5)℃ 10分钟, 最大温差≤10℃, 漂移≤2℃"; + txtBalanceStatus.Text = "温度平衡状态: 判断中..."; + balanceStatusBorder.Background = new SolidColorBrush(Colors.Gray); + txtBalanceResult.Text = "判断中"; + + // 更新目标温度显示(如果存在) + if (txtTestTemp != null) + { + txtTestTemp.Text = "750"; // 标准目标温度 + } + } + + private void StartBalanceCheck() + { + // 停止现有定时器 + _balanceTimer?.Stop(); + + // 创建新的平衡判断定时器(每秒检查一次) + _balanceTimer = new DispatcherTimer(); + _balanceTimer.Interval = TimeSpan.FromSeconds(1); + _balanceTimer.Tick += BalanceTimer_Tick_Standard; + + // 启动定时器 + _balanceTimer.Start(); + _isBalanceChecking = true; + } + + private void BalanceTimer_Tick_Standard(object sender, EventArgs e) + { + try + { + // 1. 计时递增 + _balanceElapsedSeconds++; + UpdateBalanceTimeDisplay(); + + // 2. 采集当前炉内温度(标准7.4.6要求记录炉内温度) + double currentTemp = GetCurrentFurnaceTemperature(); + + // 3. 记录温度数据 + RecordTemperatureData(currentTemp); + + // 4. 每10秒检查一次平衡状态 + if (_balanceElapsedSeconds % 10 == 0) + { + CheckBalanceStatus(); + } + + // 5. 达到10分钟时进行最终判断 + if (_balanceElapsedSeconds >= _balanceTotalSeconds) + { + CompleteBalanceCheck(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"温度平衡判断出错:{ex.Message}"); + HandleBalanceError(ex); + } + } + + private double GetCurrentFurnaceTemperature() + { + try + { + // 标准4.4.3:炉内热电偶位于加热炉管高度的中点,距管壁(10±0.5)mm + ushort[] registers = _modbusMaster.ReadHoldingRegisters(1, 1230, 2); + if (registers != null && registers.Length >= 2) + { + return c.UshortToFloat(registers[1], registers[0]); + } + return 0.0; + } + catch (Exception ex) + { + Debug.WriteLine($"读取炉内温度失败: {ex.Message}"); + return 0.0; + } + } + + private void RecordTemperatureData(double temperature) + { + // 记录当前温度 + _tempDataList?.Add(temperature); + + // 保持最近600秒的数据(10分钟) + if (_tempDataList?.Count > _balanceTotalSeconds) + { + _tempDataList?.RemoveAt(0); + } + } + + private void CheckBalanceStatus() + { + if (_tempDataList?.Count < 60) // 至少需要1分钟数据 + return; + + // 计算统计指标 + CalculateBalanceStatistics(); + + // 更新UI显示当前状态 + UpdateBalanceDisplay(); + + // 检查是否符合标准条件 + CheckStandardConditions(); + } + + private void CalculateBalanceStatistics() + { + if (_tempDataList?.Count == 0) return; + + double sum = 0; + double min = double.MaxValue; + double max = double.MinValue; + + foreach (var temp in _tempDataList) + { + sum += temp; + if (temp < min) min = temp; + if (temp > max) max = temp; + } + + _balanceStatistics.AverageTemp = sum / _tempDataList.Count; + _balanceStatistics.MinTemp = min; + _balanceStatistics.MaxTemp = max; + _balanceStatistics.TempRange = max - min; + + // 计算线性回归漂移(标准要求) + CalculateLinearRegression(); + } + + private void CalculateLinearRegression() + { + if (_tempDataList.Count < 10) return; + + // 取最近10分钟的数据进行线性回归分析 + int n = Math.Min(_tempDataList.Count, 600); + List recentTemps = _tempDataList.Skip(_tempDataList.Count - n).Take(n).ToList(); + + double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0; + + for (int i = 0; i < n; i++) + { + double x = i; + double y = recentTemps[i]; + sumX += x; + sumY += y; + sumXY += x * y; + sumX2 += x * x; + } + + double denominator = n * sumX2 - sumX * sumX; + if (Math.Abs(denominator) > 0.0001) + { + _balanceStatistics.LinearSlope = (n * sumXY - sumX * sumY) / denominator; + + _balanceStatistics.TenMinuteDrift = Math.Abs(_balanceStatistics.LinearSlope * 600); + } + } + + private void CheckStandardConditions() + { + // 标准条件1:平均温度在750±5℃范围内 + bool condition1 = (_balanceStatistics.AverageTemp >= 745 && + _balanceStatistics.AverageTemp <= 755); + + // 标准条件2:最大温差不超过10℃(最高与平均的偏差) + double maxDeviation = Math.Max( + Math.Abs(_balanceStatistics.MaxTemp - _balanceStatistics.AverageTemp), + Math.Abs(_balanceStatistics.MinTemp - _balanceStatistics.AverageTemp) + ); + bool condition2 = maxDeviation <= 10; + + // 标准条件3:10分钟内温度漂移不超过2℃ + bool condition3 = _balanceStatistics.TenMinuteDrift <= 2; + + // 更新平衡状态 + _balanceStatistics.IsBalanced = condition1 && condition2 && condition3; + + // 保存条件结果 + _balanceStatistics.Condition1 = condition1; + _balanceStatistics.Condition2 = condition2; + _balanceStatistics.Condition3 = condition3; + } + + private void UpdateBalanceDisplay() + { + Dispatcher.Invoke(() => + { + // 更新计时显示 + int minutes = _balanceElapsedSeconds / 60; + int seconds = _balanceElapsedSeconds % 60; + txtBalanceTimeElapsed.Text = $"{minutes:D2}:{seconds:D2}"; + + // 更新条件显示 + string conditionText = $"平衡条件: 炉温({_balanceStatistics.AverageTemp:F1}℃) " + + $"最大温差:{Math.Max(Math.Abs(_balanceStatistics.MaxTemp - _balanceStatistics.AverageTemp), Math.Abs(_balanceStatistics.MinTemp - _balanceStatistics.AverageTemp)):F1}℃ " + + $"漂移:{_balanceStatistics.TenMinuteDrift:F2}℃"; + txtBalanceCondition.Text = conditionText; + + // 更新状态文本 + txtBalanceStatus.Text = $"温度平衡状态: 采集{_tempDataList.Count}个数据点"; + + // 更新结果指示 + if (_balanceElapsedSeconds < _balanceTotalSeconds) + { + txtBalanceResult.Text = "采集中..."; + balanceStatusBorder.Background = new SolidColorBrush(Colors.Orange); + } + }); + } + + private void CompleteBalanceCheck() + { + // 停止定时器 + _balanceTimer.Stop(); + _isBalanceChecking = false; + + // 进行最终计算 + CalculateBalanceStatistics(); + CheckStandardConditions(); + + // 显示最终结果 + DisplayFinalResult(); + + // 记录日志 + LogBalanceResult(); + + UpdateStatusBar($"温度平衡判断完成: {(_balanceStatistics.IsBalanced ? "达到标准" : "未达到标准")}"); + } + + private void DisplayFinalResult() + { + Dispatcher.Invoke(() => + { + if (_balanceStatistics.IsBalanced) + { + // 达到平衡标准 + balanceStatusBorder.Background = new SolidColorBrush(Colors.Green); + txtBalanceResult.Text = "已平衡"; + txtBalanceStatus.Text = $"温度平衡状态: 达到GB/T 5464-2010标准\n" + + $"平均温度: {_balanceStatistics.AverageTemp:F1}℃\n" + + $"最大温差: {Math.Max(Math.Abs(_balanceStatistics.MaxTemp - _balanceStatistics.AverageTemp), Math.Abs(_balanceStatistics.MinTemp - _balanceStatistics.AverageTemp)):F1}℃\n" + + $"10分钟漂移: {_balanceStatistics.TenMinuteDrift:F2}℃"; + } + else + { + // 未达到平衡标准 + balanceStatusBorder.Background = new SolidColorBrush(Colors.Red); + txtBalanceResult.Text = "未平衡"; + + string failureReasons = "未满足条件:"; + if (!_balanceStatistics.Condition1) + failureReasons += " 平均温度不在745-755℃范围"; + if (!_balanceStatistics.Condition2) + failureReasons += " 最大温差>10℃"; + if (!_balanceStatistics.Condition3) + failureReasons += " 10分钟漂移>2℃"; + + txtBalanceStatus.Text = $"温度平衡状态: 未达到标准\n{failureReasons}"; + } + }); + } + + private void LogBalanceResult() + { + try + { + string logContent = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 温度平衡判断结果\n" + + $"执行标准: GB/T 5464-2010\n" + + $"判断时长: {_balanceElapsedSeconds}秒\n" + + $"平均温度: {_balanceStatistics.AverageTemp:F1}℃\n" + + $"温度范围: {_balanceStatistics.MinTemp:F1}℃ ~ {_balanceStatistics.MaxTemp:F1}℃\n" + + $"最大温差: {Math.Max(Math.Abs(_balanceStatistics.MaxTemp - _balanceStatistics.AverageTemp), Math.Abs(_balanceStatistics.MinTemp - _balanceStatistics.AverageTemp)):F1}℃\n" + + $"10分钟漂移: {_balanceStatistics.TenMinuteDrift:F2}℃\n" + + $"平衡状态: {(_balanceStatistics.IsBalanced ? "达到标准" : "未达到标准")}\n" + + $"符合条件: 平均温度{(_balanceStatistics.Condition1 ? "√" : "×")} " + + $"最大温差{(_balanceStatistics.Condition2 ? "√" : "×")} " + + $"温度漂移{(_balanceStatistics.Condition3 ? "√" : "×")}\n"; + + // 保存到日志文件 + string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs", "BalanceLog.txt"); + Directory.CreateDirectory(Path.GetDirectoryName(logPath)); + File.AppendAllText(logPath, logContent + Environment.NewLine); + } + catch (Exception ex) + { + Debug.WriteLine($"记录平衡日志失败: {ex.Message}"); + } + } + + private void HandleBalanceError(Exception ex) + { + _balanceTimer.Stop(); + _isBalanceChecking = false; + + Dispatcher.Invoke(() => + { + balanceStatusBorder.Background = new SolidColorBrush(Colors.Red); + txtBalanceResult.Text = "错误"; + txtBalanceStatus.Text = $"温度平衡判断出错: {ex.Message}"; + }); + + UpdateStatusBar("温度平衡判断出错"); + } + + private void UpdateBalanceTimeDisplay() + { + Dispatcher.Invoke(() => + { + int minutes = _balanceElapsedSeconds / 60; + int seconds = _balanceElapsedSeconds % 60; + txtBalanceTimeElapsed.Text = $"{minutes:D2}:{seconds:D2}"; + }); + } + #endregion + + #region 平衡统计类 + private BalanceStatistics _balanceStatistics; + private double _targetTemperature; + + private class BalanceStatistics + { + public double AverageTemp { get; set; } + public double MinTemp { get; set; } + public double MaxTemp { get; set; } + public double TempRange { get; set; } + public double LinearSlope { get; set; } + public double TenMinuteDrift { get; set; } + public bool IsBalanced { get; set; } + public bool Condition1 { get; set; } + public bool Condition2 { get; set; } + public bool Condition3 { get; set; } + } + #endregion + private void OpenBalanceChartWindow() + { + try + { + // 使用异步避免阻塞 + Dispatcher.BeginInvoke(new Action(() => + { + try + { + // 创建窗口但不立即初始化 + var chartWindow = new BalanceChartWindow(() => + { + try + { + if (_modbusMaster != null && _tcpClient != null && _tcpClient.Connected) + { + ushort[] registers = _modbusMaster.ReadHoldingRegisters(1, 1230, 2); + if (registers != null && registers.Length >= 2) + { + return c.UshortToFloat(registers[1], registers[0]); + } + } + return 0.0; + } + catch { return 0.0; } + }); + + chartWindow.Owner = this; + chartWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; + + // 延迟显示 + chartWindow.Show(); + + UpdateStatusBar("打开温度平衡曲线图"); + } + catch (Exception ex) + { + MessageBox.Show($"无法打开温度曲线图: {ex.Message}", "错误"); + } + }), DispatcherPriority.Background); + } + catch (Exception ex) + { + MessageBox.Show($"打开图表窗口失败: {ex.Message}", "错误"); + } + } + + private void btnStopBalanceCheck_Click(object sender, RoutedEventArgs e) + { + if (!_isBalanceChecking) + { + MessageBox.Show("当前未进行温度平衡判断", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + return; + } + + // 停止定时器 + _balanceTimer.Stop(); + _isBalanceChecking = false; + + // 如果已经采集了足够数据,进行最终判断 + if (_tempDataList.Count >= 60) // 至少1分钟数据 + { + CalculateBalanceStatistics(); + CheckStandardConditions(); + DisplayFinalResult(); + } + else + { + // 数据不足,显示提示 + Dispatcher.Invoke(() => + { + txtBalanceStatus.Text = $"温度平衡状态: 已手动停止(数据不足,仅采集{_tempDataList.Count}秒)"; + txtBalanceResult.Text = "数据不足"; + balanceStatusBorder.Background = new SolidColorBrush(Colors.Orange); + }); + } + + UpdateStatusBar($"温度平衡判断已停止(已采集{_tempDataList.Count}秒数据)"); + } + #endregion + + + + #region 最终平衡代码 + + + + + // 初始化试验结束平衡 + private void InitializeFinalBalance() + { + _finalBalanceTimer = new DispatcherTimer(); + _finalBalanceTimer.Interval = TimeSpan.FromSeconds(1); + _finalBalanceTimer.Tick += FinalBalanceTimer_Tick; + _finalTempData = new List(); + } + + // 试验结束温度平衡定时器 + private void FinalBalanceTimer_Tick(object sender, EventArgs e) + { + //if (!_isTestRunning || !_isFinalBalanceChecking) return; + + try + { + // 获取当前温度 + double currentTemp = GetCurrentFurnaceTemp(); + _finalTempData.Add(currentTemp); + + // 更新最高温度 + if (currentTemp > _finalMaxTemp) + _finalMaxTemp = currentTemp; + + // 检查是否达到30分钟 + TimeSpan elapsed = DateTime.Now.TimeOfDay - _finalBalanceStartTime; + double currentDrift = 0; + if (_finalTempData.Count >= 600) // 有足够数据计算漂移 + { + var recentData = _finalTempData.Skip(Math.Max(0, _finalTempData.Count - 600)).ToList(); + double slope = CalculateLinearRegressionSlope(recentData); // 使用你现有的方法 + currentDrift = Math.Abs(slope * 600); // 10分钟的漂移量 + } + // 更新UI信息(每秒更新) + UpdateFinalBalanceInfo(elapsed, _finalTempData.Count, currentTemp, + _finalInitialTemp, _finalMaxTemp, currentDrift); + if (elapsed.TotalMinutes >= 30) + { + // 检查最终温度平衡条件 + CheckFinalTemperatureBalance(); + + // 如果达到60分钟,强制结束 + if (elapsed.TotalMinutes >= 60) + { + CompleteFinalBalance(true); + } + } + } + catch (Exception ex) + { + Debug.WriteLine($"试验结束平衡检查出错: {ex.Message}"); + } + } + + // 检查最终温度平衡(标准7.4.7) + private void CheckFinalTemperatureBalance() + { + if (_finalTempData.Count < 600) return; // 至少10分钟数据 + + // 取最近10分钟的数据 + var recentData = _finalTempData.Skip(Math.Max(0, _finalTempData.Count - 600)).ToList(); + + // 计算线性回归漂移 + double slope = CalculateLinearRegressionSlope(recentData); + double drift = Math.Abs(slope * 600); // 10分钟的漂移量 + + // 更新漂移值显示 + UpdateFinalBalanceInfo(DateTime.Now.TimeOfDay - _finalBalanceStartTime, + _finalTempData.Count, _finalTempData.Last(), + _finalInitialTemp, _finalMaxTemp, drift); + + // 检查条件:10分钟内漂移不超过2°C + if (drift <= 2.0) + { + // 达到温度平衡 + CompleteFinalBalance(false); + } + } + + // 计算线性回归斜率 + private double CalculateLinearRegressionSlope(List data) + { + if (data.Count < 2) return 0; + + double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0; + int n = data.Count; + + for (int i = 0; i < n; i++) + { + double x = i; + double y = data[i]; + sumX += x; + sumY += y; + sumXY += x * y; + sumX2 += x * x; + } + + double denominator = n * sumX2 - sumX * sumX; + if (Math.Abs(denominator) < 0.0001) return 0; + + return (n * sumXY - sumX * sumY) / denominator; + } + + private void CompleteFinalBalance(bool isForced) + { + _isFinalBalanceChecking = false; + _finalBalanceTimer.Stop(); + + // === 新增:同时停止试验 === + _isTestRunning = false; + _testTimer.Stop(); + // =========================== + + // 计算最终温度(最后1分钟平均值) + int count = Math.Min(_finalTempData.Count, 60); + var lastMinuteData = _finalTempData.Skip(_finalTempData.Count - count).ToList(); + _finalFinalTemp = lastMinuteData.Average(); + + // 记录试验结束时间 + TimeSpan testDuration = DateTime.Now.TimeOfDay - _finalBalanceStartTime; + // 更新最终UI状态 + string resultText = isForced ? "强制结束" : "达到平衡"; + Brush resultColor = isForced ? Brushes.Red : Brushes.Green; + UpdateFinalBalanceUI("已完成", resultText, resultColor); + + // 更新最终漂移值显示 + double finalDrift = 0; + if (_finalTempData.Count >= 600) + { + var recentData = _finalTempData.Skip(Math.Max(0, _finalTempData.Count - 600)).ToList(); + double slope = CalculateLinearRegressionSlope(recentData); + finalDrift = Math.Abs(slope * 600); + UpdateFinalBalanceInfo(testDuration, _finalTempData.Count, _finalFinalTemp, + _finalInitialTemp, _finalMaxTemp, finalDrift); + } + // 更新状态显示 + Dispatcher.Invoke(() => + { + txtTestTime.Text = testDuration.ToString(@"hh\:mm\:ss"); + progressBar.Width = 400; // 进度条满 + txtProgress.Text = "100%"; + + // 显示平衡结果 + string result = isForced ? "60分钟强制结束" : "达到温度平衡"; + UpdateStatusBar($"试验结束: {result}"); + + // === 新增:更新系统状态 === + txtSystemStatus.Text = "试验结束"; + statusIndicator2.Fill = new SolidColorBrush(Colors.Green); + btnStartTest.IsEnabled = true; + btnStop.IsEnabled = false; + // ========================= + + // 自动填入试验结束重量(如果未填写) + if (string.IsNullOrEmpty(txtFinalWeight.Text) || txtFinalWeight.Text == "请输入试验后重量(g)") + { + EnableFinalWeightInput(); + MessageBox.Show("试验已结束,请进行后称重并输入试验后重量。", + "后称重提醒", MessageBoxButton.OK, MessageBoxImage.Information); + } + + // 自动保存试验数据到报表 + SaveTestDataToReport(); + }); + } + + // 开始试验结束平衡判断 + private void StartFinalBalanceCheck() + { + _finalTempData.Clear(); + _finalInitialTemp = GetCurrentFurnaceTemp(); + _finalMaxTemp = _finalInitialTemp; + _finalBalanceStartTime = DateTime.Now.TimeOfDay; + _isFinalBalanceChecking = true; + _finalBalanceTimer.Start(); + + // 更新UI状态 + UpdateFinalBalanceUI("判断中", "判断中...", Brushes.Orange); + UpdateFinalBalanceInfo(TimeSpan.Zero, 0, _finalInitialTemp, + _finalInitialTemp, _finalMaxTemp); + + UpdateStatusBar("开始试验结束温度平衡判断"); + } + // 重置最终平衡UI状态 + private void ResetFinalBalanceUI() + { + UpdateFinalBalanceUI("未开始", "等待开始", Brushes.Gray); + UpdateFinalBalanceInfo(TimeSpan.Zero, 0, 0, 0, 0, 0); + } + // 停止试验结束平衡判断 + private void StopFinalBalanceCheck() + { + _isFinalBalanceChecking = false; + _finalBalanceTimer.Stop(); + // 更新UI状态 + UpdateFinalBalanceUI("已停止", "手动停止", Brushes.Gray); + } + + + // 更新最终平衡UI状态 + private void UpdateFinalBalanceUI(string status, string statusText, Brush statusColor) + { + if (Dispatcher.CheckAccess()) + { + txtFinalBalanceState.Text = status; + txtFinalBalanceStatusText.Text = statusText; + finalBalanceStatusBorder.Background = statusColor; + } + else + { + Dispatcher.Invoke(() => UpdateFinalBalanceUI(status, statusText, statusColor)); + } + } + + // 更新最终平衡计时和温度显示 + private void UpdateFinalBalanceInfo(TimeSpan elapsed, int dataCount, double currentTemp, + double initialTemp, double maxTemp, double drift = 0) + { + if (Dispatcher.CheckAccess()) + { + // 更新时间显示(格式:mm:ss) + txtFinalBalanceTimer.Text = $"{(int)elapsed.TotalMinutes:D2}:{elapsed.Seconds:D2}"; + + // 更新温度数据 + txtFinalBalanceInitialTemp.Text = $"{initialTemp:F1}°C"; + txtFinalBalanceMaxTemp.Text = $"{maxTemp:F1}°C"; + txtFinalBalanceCurrentTemp.Text = $"{currentTemp:F1}°C"; + + // 更新数据统计 + txtFinalBalanceDataCount.Text = dataCount.ToString(); + txtFinalBalanceDrift.Text = $"{drift:F2}°C"; + } + else + { + Dispatcher.Invoke(() => UpdateFinalBalanceInfo(elapsed, dataCount, currentTemp, + initialTemp, maxTemp, drift)); + } + } + + // 保存试验数据到报表 + private void SaveTestDataToReport() + { + try + { + // 获取报表窗口实例 + TestReportWindow reportWindow = Application.Current.Windows + .OfType() + .FirstOrDefault(); + + //if (reportWindow == null) return; + + // 解析重量数据 + double initialWeight = GetDoubleValue(txtInitialWeight.Text); + double finalWeight = GetDoubleValue(txtFinalWeight.Text); + double weightLossPercent = 0; + + if (initialWeight > 0 && finalWeight > 0) + { + weightLossPercent = ((initialWeight - finalWeight) / initialWeight) * 100; + } + + // 解析火焰持续时间 + int flameDuration = 0; + if (!string.IsNullOrEmpty(txtCombustionNote.Text)) + { + int.TryParse(txtCombustionNote.Text, out flameDuration); + } + + // 创建报表数据对象 + var reportData = new TestReportData + { + SampleCode = txtTestNo.Text, + SampleName = txtSampleName.Text, + SampleSpec = txtSampleSpec.Text, + InitialTemp = _finalInitialTemp, + MaxTemp = _finalMaxTemp, + FinalTemp = _finalFinalTemp, + TempRise = _finalMaxTemp - _finalInitialTemp, + InitialWeight = initialWeight, + FinalWeight = finalWeight, + LossPercent = weightLossPercent, + FlameDuration = flameDuration, + TestDate = DateTime.Now.ToString("yyyy-MM-dd"), + TestDuration = txtTestTime.Text, + BalanceStatus = "达到平衡", + Remarks = $"火焰:{(chkHasFlame.IsChecked == true ? "有" : "无")} 冒烟:{(chkHasSmoke.IsChecked == true ? "有" : "无")}" + }; + + + + + SaveDataToTempFile(reportData); + + + UpdateStatusBar("试验数据已保存到报表"); + } + catch (Exception ex) + { + Debug.WriteLine($"保存数据到报表失败: {ex.Message}"); + } + } + + // 临时保存数据到文件(在主窗口类中添加这个方法) + private void SaveDataToTempFile(TestReportData reportData) + { + try + { + // 使用简单的文本格式保存 + string dataLine = $"{reportData.SampleCode}|{reportData.SampleName}|" + + $"{reportData.SampleSpec}|{reportData.InitialTemp:F1}|" + + $"{reportData.MaxTemp:F1}|{reportData.FinalTemp:F1}|" + + $"{reportData.TempRise:F1}|{reportData.InitialWeight:F2}|" + + $"{reportData.FinalWeight:F2}|{reportData.LossPercent:F2}|" + + $"{reportData.FlameDuration}|{reportData.TestDate}|" + + $"{reportData.TestDuration}|{reportData.BalanceStatus}|" + + $"{reportData.Remarks}"; + + string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TempReportData.txt"); + + // 追加数据到文件 + File.AppendAllText(filePath, dataLine + Environment.NewLine, Encoding.UTF8); + + Debug.WriteLine($"数据已临时保存到文件: {filePath}"); + } + catch (Exception ex) + { + Debug.WriteLine($"临时保存数据失败: {ex.Message}"); + } + } + + + #endregion } } diff --git a/建材不燃性试验炉/TestReportWindow.xaml b/建材不燃性试验炉/TestReportWindow.xaml index 2c3f67b..a202e9e 100644 --- a/建材不燃性试验炉/TestReportWindow.xaml +++ b/建材不燃性试验炉/TestReportWindow.xaml @@ -84,51 +84,25 @@ ColumnHeaderStyle="{StaticResource DataGridHeaderStyle}"> - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -141,10 +115,10 @@ - - + @@ -188,7 +162,7 @@ Height="40" Style="{StaticResource OperationButtonStyle}" Background="#3498DB" - BorderBrush="#3498DB" Click="btnReturn_Click"> + BorderBrush="#3498DB" > diff --git a/建材不燃性试验炉/TestReportWindow.xaml.cs b/建材不燃性试验炉/TestReportWindow.xaml.cs index baa415e..090673e 100644 --- a/建材不燃性试验炉/TestReportWindow.xaml.cs +++ b/建材不燃性试验炉/TestReportWindow.xaml.cs @@ -1,5 +1,10 @@ -using System; +using jiancaiburanxing.data; +using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -12,6 +17,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using 建材不燃性试验炉; +using Path = System.IO.Path; namespace jiancaiburanxing { @@ -20,13 +26,239 @@ namespace jiancaiburanxing /// public partial class TestReportWindow : Window { + + private ObservableCollection _testData; + private ICollectionView _testDataView; #region 构造函数和初始化 public TestReportWindow() { InitializeComponent(); + InitializeDataGrid(); + LoadTestData(); } #endregion + + private void InitializeDataGrid() + { + _testData = new ObservableCollection(); + _testDataView = CollectionViewSource.GetDefaultView(_testData); + dgTestReport.ItemsSource = _testDataView; + + // 设置按钮事件 + btnClearData.Click += BtnClearData_Click; + btnExportReport.Click += BtnExportReport_Click; + btnReturn.Click += btnReturn_Click; + } + + // 加载试验数据 + private void LoadTestData() + { + try + { + LoadTempDataFromFile(); + //AddSampleData(); + } + catch (Exception ex) + { + MessageBox.Show($"加载数据失败: {ex.Message}", "错误", + MessageBoxButton.OK, MessageBoxImage.Error); + } + } + // 可选:从临时文件加载数据 + private void LoadTempDataFromFile() + { + try + { + string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TempReportData.txt"); + if (!File.Exists(filePath)) return; + + var lines = File.ReadAllLines(filePath, Encoding.UTF8); + foreach (var line in lines) + { + var parts = line.Split('|'); + if (parts.Length >= 14) + { + var reportData = new TestReportData + { + SampleCode = parts[0], + SampleName = parts[1], + SampleSpec = parts[2], + InitialTemp = double.Parse(parts[3]), + MaxTemp = double.Parse(parts[4]), + FinalTemp = double.Parse(parts[5]), + TempRise = double.Parse(parts[6]), + InitialWeight = double.Parse(parts[7]), + FinalWeight = double.Parse(parts[8]), + LossPercent = double.Parse(parts[9]), + FlameDuration = int.Parse(parts[10]), + TestDate = parts[11], + TestDuration = parts[12], + BalanceStatus = parts[13], + Remarks = parts.Length > 14 ? parts[14] : "" + }; + + _testData.Add(reportData); + } + } + + Debug.WriteLine($"从临时文件加载了 {_testData.Count} 条数据"); + } + catch (Exception ex) + { + Debug.WriteLine($"加载临时数据失败: {ex.Message}"); + } + } + //// 添加示例数据 + //private void AddSampleData() + //{ + // _testData.Add(new TestReportData + // { + // SampleCode = "TEST001", + // SampleName = "岩棉板", + // SampleSpec = "50mm", + // InitialTemp = 750.0, + // MaxTemp = 877.8, + // FinalTemp = 802.3, + // TempRise = 75.5, + // CenterMaxTemp = 850.0, + // CenterFinalTemp = 800.0, + // SurfaceMaxTemp = 900.0, + // SurfaceFinalTemp = 820.0, + // InitialWeight = 45.32, + // FinalWeight = 44.78, + // LossPercent = 1.19, + // FlameDuration = 0, + // TestDate = DateTime.Now.ToString("yyyy-MM-dd"), + // TestDuration = "30:00", + // BalanceStatus = "达到平衡", + // Remarks = "符合标准GB/T 5464-2010" + // }); + //} + + // 导出报表 + private void BtnExportReport_Click(object sender, RoutedEventArgs e) + { + try + { + var saveDialog = new Microsoft.Win32.SaveFileDialog + { + Filter = "Excel文件 (*.xlsx)|*.xlsx|CSV文件 (*.csv)|*.csv|所有文件 (*.*)|*.*", + FileName = $"不燃性试验报告_{DateTime.Now:yyyyMMdd_HHmmss}", + DefaultExt = ".xlsx" + }; + + if (saveDialog.ShowDialog() == true) + { + ExportToExcel(saveDialog.FileName); + MessageBox.Show($"报表已导出到:\n{saveDialog.FileName}", "导出成功", + MessageBoxButton.OK, MessageBoxImage.Information); + } + } + catch (Exception ex) + { + MessageBox.Show($"导出失败: {ex.Message}", "错误", + MessageBoxButton.OK, MessageBoxImage.Error); + } + } + + + + // 导出到Excel(简化版本) + private void ExportToExcel(string filePath) + { + using (var writer = new StreamWriter(filePath, false, Encoding.UTF8)) + { + // 写入标题 + writer.WriteLine("建材不燃性试验数据报表"); + writer.WriteLine($"生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}"); + writer.WriteLine("符合标准: GB/T 5464-2010"); + writer.WriteLine(); + + // 写入表头 + writer.WriteLine("试样编号,试样名称,试样规格,炉内初始温度(℃),炉内最高温度(℃),炉内最终温度(℃),温升(℃)," + + "试样中心最高温度(℃),试样中心最终温度(℃),试样表面最高温度(℃),试样表面最终温度(℃)," + + "试样初始质量(g),试样结束质量(g),质量损失(%),火焰持续时间(s),试验日期,试验持续时间,平衡状态,备注"); + + // 写入数据 + foreach (var item in _testData) + { + writer.WriteLine($"{item.SampleCode},{item.SampleName},{item.SampleSpec}," + + $"{item.InitialTemp:F1},{item.MaxTemp:F1},{item.FinalTemp:F1},{item.TempRise:F1}," + + $"{item.CenterMaxTemp:F1},{item.CenterFinalTemp:F1},{item.SurfaceMaxTemp:F1},{item.SurfaceFinalTemp:F1}," + + $"{item.InitialWeight:F2},{item.FinalWeight:F2},{item.LossPercent:F2}," + + $"{item.FlameDuration},{item.TestDate},{item.TestDuration},{item.BalanceStatus},{item.Remarks}"); + } + } + } + + + + + // 添加新的试验数据(由主窗口调用) + public void AddTestReportData(TestReportData data) + { + Dispatcher.Invoke(() => + { + _testData.Insert(0, data); // 插入到开头 + }); + } + + // 清空数据 + private void BtnClearData_Click(object sender, RoutedEventArgs e) + { + var result = MessageBox.Show("确定要清空所有报表数据吗?此操作不可恢复。", + "确认清空", MessageBoxButton.YesNo, MessageBoxImage.Warning); + + if (result == MessageBoxResult.Yes) + { + _testData.Clear(); + DeleteJsonDataFile(); + MessageBox.Show("数据已清空", "提示", + MessageBoxButton.OK, MessageBoxImage.Information); + } + } + // 删除JSON数据文件 + private void DeleteJsonDataFile() + { + try + { + // 假设你的JSON文件路径(根据你的实际情况调整) + string jsonFilePath = Path.Combine( + AppDomain.CurrentDomain.BaseDirectory, + "TestReportData.json"); + + // 如果文件存在,就删除 + if (File.Exists(jsonFilePath)) + { + File.Delete(jsonFilePath); + Debug.WriteLine($"JSON数据文件已删除: {jsonFilePath}"); + } + else + { + Debug.WriteLine($"JSON数据文件不存在: {jsonFilePath}"); + } + + + string tempFilePath = Path.Combine( + AppDomain.CurrentDomain.BaseDirectory, + "TempReportData.txt"); + + if (File.Exists(tempFilePath)) + { + File.Delete(tempFilePath); + Debug.WriteLine($"临时数据文件已删除: {tempFilePath}"); + } + + } + catch (Exception ex) + { + // 记录错误但不影响主流程 + Debug.WriteLine($"删除JSON数据文件失败: {ex.Message}"); + + + } + } #region 切换主页相关 private MainWindow _mainWindow; @@ -63,6 +295,6 @@ namespace jiancaiburanxing #endregion - + } } diff --git a/建材不燃性试验炉/data/ReportData.cs b/建材不燃性试验炉/data/ReportData.cs index 871ee11..2ac137f 100644 --- a/建材不燃性试验炉/data/ReportData.cs +++ b/建材不燃性试验炉/data/ReportData.cs @@ -10,13 +10,13 @@ namespace jiancaiburanxing.data { #region 试验属性 - public string Num { get; set; } //试验编号 + public string Num { get; set; } //试验编号 public string Name { get; set; }//试验名称 public string Specs { get; set; }//试验规格 - public float InitialFurnaceTemperature { get; set; }//炉内初始温度 + public float InitialFurnaceTemperature { get; set; }//炉内初始温度 public float HighFurnaceTemperature { get; set; }//炉内最高温度 @@ -42,4 +42,29 @@ namespace jiancaiburanxing.data #endregion } + + #region 数据模型和集合 + public class TestReportData + { + public string SampleCode { get; set; } // 试样编号 + public string SampleName { get; set; } // 试样名称 + public string SampleSpec { get; set; } // 试样规格 + public double InitialTemp { get; set; } // 炉内初始温度 + public double MaxTemp { get; set; } // 炉内最高温度 + public double FinalTemp { get; set; } // 炉内最终温度 + public double TempRise { get; set; } // 温升 + public double CenterMaxTemp { get; set; } // 试样中心最高温度 + public double CenterFinalTemp { get; set; } // 试样中心最终温度 + public double SurfaceMaxTemp { get; set; } // 试样表面最高温度 + public double SurfaceFinalTemp { get; set; } // 试样表面最终温度 + public double InitialWeight { get; set; } // 试样初始质量 + public double FinalWeight { get; set; } // 试样结束质量 + public double LossPercent { get; set; } // 质量损失百分比 + public int FlameDuration { get; set; } // 火焰持续时间 + public string TestDate { get; set; } // 试验日期 + public string TestDuration { get; set; } // 试验持续时间 + public string BalanceStatus { get; set; } // 平衡状态 + public string Remarks { get; set; } // 备注 + } + #endregion } diff --git a/建材不燃性试验炉/建材不燃性试验炉.csproj b/建材不燃性试验炉/建材不燃性试验炉.csproj index 2798d75..63ea4f1 100644 --- a/建材不燃性试验炉/建材不燃性试验炉.csproj +++ b/建材不燃性试验炉/建材不燃性试验炉.csproj @@ -2,7 +2,7 @@ WinExe - net7.0-windows + net8.0-windows7.0 true jiancaiburanxing jiancaiburanxing @@ -12,19 +12,20 @@ + - ..\..\..\..\..\..\Program Files\腾讯电脑管家软件搬家\软件搬家\DevExpress Components 22.2\Bin\Framework\DevExpress.Charts.v22.2.Core.dll + bin\Debug\net8.0-windows7.0\DevExpress.Charts.v22.2.Core.dll ..\..\..\..\..\..\Program Files\腾讯电脑管家软件搬家\软件搬家\DevExpress Components 22.2\Bin\Framework\DevExpress.Data.v22.2.dll - ..\..\..\..\..\..\Program Files\腾讯电脑管家软件搬家\软件搬家\DevExpress Components 22.2\Bin\Framework\DevExpress.Xpf.Charts.v22.2.dll + bin\Debug\net8.0-windows7.0\DevExpress.Xpf.Charts.v22.2.dll ..\..\..\..\..\..\Program Files\腾讯电脑管家软件搬家\软件搬家\DevExpress Components 22.2\Bin\Framework\DevExpress.Xpf.Core.v22.2.dll