Compare commits
7 Commits
76c911084e
...
xyy
| Author | SHA1 | Date | |
|---|---|---|---|
| 8419aaaccd | |||
| 4764ca789b | |||
| 9eb7c54ac8 | |||
| abc3e186e2 | |||
| 8573f5c4e5 | |||
| d3fdb6a288 | |||
| 2c20eaf323 |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
<TargetFramework>net10.0-windows7.0</TargetFramework>
|
||||||
<RootNamespace>ASTM_D7896_19瞬态热线法</RootNamespace>
|
<RootNamespace>ASTM_D7896_19瞬态热线法</RootNamespace>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
@@ -16,11 +16,11 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||||
<PackageReference Include="EPPlus" Version="7.0.3" />
|
<PackageReference Include="EPPlus" Version="7.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.16" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.8" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.8" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.8" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.8" />
|
||||||
<PackageReference Include="NModbus4.NetCore" Version="3.0.0" />
|
<PackageReference Include="NModbus4.NetCore" Version="4.0.0" />
|
||||||
<PackageReference Include="OxyPlot.Wpf" Version="2.2.0" />
|
<PackageReference Include="OxyPlot.Wpf" Version="2.2.0" />
|
||||||
<PackageReference Include="PdfSharpCore" Version="1.3.67" />
|
<PackageReference Include="PdfSharpCore" Version="1.3.67" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
BIN
CSI-L028瞬态热线法导热系数测试仪器(1).gxw
Normal file
BIN
CSI-L028瞬态热线法导热系数测试仪器(1).gxw
Normal file
Binary file not shown.
BIN
CSI-L028瞬态热线法导热系数测试仪器(1).pdf
Normal file
BIN
CSI-L028瞬态热线法导热系数测试仪器(1).pdf
Normal file
Binary file not shown.
@@ -46,7 +46,7 @@ public class TestParameters
|
|||||||
public int MeasurementCount { get; set; } = 10;
|
public int MeasurementCount { get; set; } = 10;
|
||||||
[Range(5, 300)]
|
[Range(5, 300)]
|
||||||
public int IntervalSeconds { get; set; } = 30;
|
public int IntervalSeconds { get; set; } = 30;
|
||||||
public double PlatinumWireLength { get; set; } = 0.040; // 默认 5.6 cm
|
public double PlatinumWireLength { get; set; } = 0.04; // 默认 5.6 cm
|
||||||
public double PlatinumWireDiameter { get; set; } = 0.00006;
|
public double PlatinumWireDiameter { get; set; } = 0.00006;
|
||||||
public string ReportOutputPath { get; set; } = "Reports\\";
|
public string ReportOutputPath { get; set; } = "Reports\\";
|
||||||
|
|
||||||
@@ -91,6 +91,6 @@ public class CalibrationCoefficients
|
|||||||
public ushort PressureProtection { get; set; }
|
public ushort PressureProtection { get; set; }
|
||||||
public ushort TemperatureCoefficient { get; set; }
|
public ushort TemperatureCoefficient { get; set; }
|
||||||
public ushort ResistanceCoefficient { get; set; }
|
public ushort ResistanceCoefficient { get; set; }
|
||||||
public double ThermalConductivityCorrection { get; set; } = 47.305349f;//蒸馏水 比热率修正
|
public double ThermalConductivityCorrection { get; set; } = 37;//蒸馏水 比热率修正
|
||||||
public double ThermalDiffusivityCorrection { get; set; } = 0.312912;//导热率修正
|
public double ThermalDiffusivityCorrection { get; set; } = 0.45;//导热率修正
|
||||||
}
|
}
|
||||||
@@ -12,14 +12,11 @@ using PdfSharpCore.Pdf;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Ports;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Threading;
|
|
||||||
|
|
||||||
namespace ASTM_D7896_Tester.ViewModels;
|
namespace ASTM_D7896_Tester.ViewModels;
|
||||||
|
|
||||||
@@ -55,7 +52,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
[ObservableProperty] private PlotModel _temperatureCurveModel;
|
[ObservableProperty] private PlotModel _temperatureCurveModel;
|
||||||
|
|
||||||
// UI 绑定属性 (与之前一致)
|
// UI 绑定属性 (与之前一致)
|
||||||
public ObservableCollection<string> ReferenceLiquids { get; } = new() { "蒸馏水", "甲苯", "乙二醇" };
|
public ObservableCollection<string> ReferenceLiquids { get; } = new() { "蒸馏水" };
|
||||||
[ObservableProperty] private string _sampleId = "未命名样品";
|
[ObservableProperty] private string _sampleId = "未命名样品";
|
||||||
[ObservableProperty] private double _testTemperature = 25.0;
|
[ObservableProperty] private double _testTemperature = 25.0;
|
||||||
[ObservableProperty] private string _testDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
[ObservableProperty] private string _testDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
@@ -124,9 +121,6 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
_th1953Ustd = new Th1963LanService();
|
_th1953Ustd = new Th1963LanService();
|
||||||
|
|
||||||
StartBackgroundMonitoring();
|
StartBackgroundMonitoring();
|
||||||
|
|
||||||
Task.Run(() => initPort());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StartBackgroundMonitoring()
|
private async void StartBackgroundMonitoring()
|
||||||
@@ -149,6 +143,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
Application.Current?.Dispatcher.Invoke(() => ChamberPressure = rawPressure);
|
Application.Current?.Dispatcher.Invoke(() => ChamberPressure = rawPressure);
|
||||||
|
|
||||||
float rawTemp = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Temperature);
|
float rawTemp = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Temperature);
|
||||||
|
rawTemp *= 1.0435f;
|
||||||
Application.Current?.Dispatcher.Invoke(() => CurrentTestTemperature = rawTemp);
|
Application.Current?.Dispatcher.Invoke(() => CurrentTestTemperature = rawTemp);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
@@ -164,8 +159,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
// }
|
// }
|
||||||
// catch { return 0; }
|
// catch { return 0; }
|
||||||
//}
|
//}
|
||||||
// 在类成员变量区域添加
|
|
||||||
private int currentSettleMs = 200; // 电流稳定等待时间(毫秒)
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task StartTestAsync()
|
private async Task StartTestAsync()
|
||||||
{
|
{
|
||||||
@@ -206,7 +200,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
BtnSet();
|
|
||||||
|
|
||||||
|
|
||||||
await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP
|
await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP
|
||||||
@@ -310,7 +304,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
double[] ustdBase = await _th1963Ustd.FetchBatchAsync();
|
double[] ustdBase = await _th1963Ustd.FetchBatchAsync();
|
||||||
double[] uptBase = await _th1953Ustd.FetchBatchAsync();
|
double[] uptBase = await _th1953Ustd.FetchBatchAsync();
|
||||||
|
|
||||||
double dynamicR0 = 1.49; // 默认值
|
double dynamicR0 = 1.476979; // 默认值
|
||||||
if (ustdBase != null && ustdBase.Length > 0 && uptBase != null && uptBase.Length > 0)
|
if (ustdBase != null && ustdBase.Length > 0 && uptBase != null && uptBase.Length > 0)
|
||||||
{
|
{
|
||||||
double sumR0 = 0; int cnt = 0;
|
double sumR0 = 0; int cnt = 0;
|
||||||
@@ -341,25 +335,21 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
await _th1963Ustd.PrepareBatchAsync(samples);
|
await _th1963Ustd.PrepareBatchAsync(samples);
|
||||||
await _th1953Ustd.PrepareBatchAsync(samples);
|
await _th1953Ustd.PrepareBatchAsync(samples);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, true);
|
await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, true);
|
||||||
// 等待电流稳定(不触发采集)
|
try { await Task.Delay(5, _testCts.Token); } catch (OperationCanceledException) { break; }
|
||||||
try { await Task.Delay(currentSettleMs, _testCts.Token); } catch (OperationCanceledException) { break; }
|
|
||||||
// 电流稳定后,触发采集
|
|
||||||
await Task.WhenAll(_th1963Ustd.TriggerAsync(), _th1953Ustd.TriggerAsync());
|
await Task.WhenAll(_th1963Ustd.TriggerAsync(), _th1953Ustd.TriggerAsync());
|
||||||
// 继续加热剩余时间(加热总时间 = 稳定等待时间 + 有效加热时间)
|
|
||||||
try { await Task.Delay((int)(heatingDuration * 1000), _testCts.Token); } catch (OperationCanceledException) { break; }
|
try { await Task.Delay((int)(heatingDuration * 1000), _testCts.Token); } catch (OperationCanceledException) { break; }
|
||||||
await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, false);
|
await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, false);
|
||||||
|
|
||||||
|
|
||||||
int remainingMs = (int)((totalDuration - heatingDuration) * 1000) + 100;
|
int remainingMs = (int)((totalDuration - heatingDuration) * 1000) + 100;
|
||||||
try { await Task.Delay(remainingMs, _testCts.Token); } catch (OperationCanceledException) { break; }
|
try { await Task.Delay(remainingMs, _testCts.Token); } catch (OperationCanceledException) { break; }
|
||||||
|
|
||||||
double[] ustd = await _th1963Ustd.FetchBatchAsync();
|
double[] ustd = await _th1963Ustd.FetchBatchAsync();
|
||||||
double[] upt = await _th1953Ustd.FetchBatchAsync();
|
double[] upt = await _th1953Ustd.FetchBatchAsync();
|
||||||
|
|
||||||
if (dynamicR0 == 1.49) // 基线无效
|
if (dynamicR0 == 1.476979) // 基线无效
|
||||||
{
|
{
|
||||||
double sumR0 = 0; int cnt = 0;
|
double sumR0 = 0; int cnt = 0;
|
||||||
for (int j = 2; j < Math.Min(6, ustd.Length); j++)
|
for (int j = 2; j < Math.Min(6, ustd.Length); j++)
|
||||||
@@ -401,7 +391,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
|
|
||||||
// ---- 异常值检测 ----
|
// ---- 异常值检测 ----
|
||||||
bool isOutlier = false;
|
bool isOutlier = false;
|
||||||
double deviationThreshold = 0.1; // 10% 偏差阈值
|
double deviationThreshold = 0.20; // 20% 偏差阈值
|
||||||
|
|
||||||
if (validCount >= 2) // 至少有两个有效数据后才开始剔除
|
if (validCount >= 2) // 至少有两个有效数据后才开始剔除
|
||||||
{
|
{
|
||||||
@@ -450,7 +440,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
// 测量间隔(即使舍弃也等待,让样品恢复)
|
// 测量间隔(即使舍弃也等待,让样品恢复)
|
||||||
if (validCount < requiredCount && !_stopRequested && attemptCount < maxAttempts)
|
if (validCount < requiredCount && !_stopRequested && attemptCount < maxAttempts)
|
||||||
{
|
{
|
||||||
try { await Task.Delay(_config.TestParameters.IntervalSeconds * 1000, _testCts.Token); } catch (OperationCanceledException) { break; }
|
try { await Task.Delay(_config.TestParameters.IntervalSeconds * 100, _testCts.Token); } catch (OperationCanceledException) { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,13 +507,12 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 滑动平均平滑(窗口大小改为 11)
|
// 滑动平均平滑(窗口5)
|
||||||
int windowSize = 40; // 原为 5
|
|
||||||
double[] smoothDeltaT = new double[n];
|
double[] smoothDeltaT = new double[n];
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
int start = Math.Max(0, i - windowSize / 2);
|
int start = Math.Max(0, i - 2);
|
||||||
int end = Math.Min(n - 1, i + windowSize / 2);
|
int end = Math.Min(n - 1, i + 2);
|
||||||
double sum = 0; int cnt = 0;
|
double sum = 0; int cnt = 0;
|
||||||
for (int j = start; j <= end; j++)
|
for (int j = start; j <= end; j++)
|
||||||
if (!double.IsNaN(deltaT[j])) { sum += deltaT[j]; cnt++; }
|
if (!double.IsNaN(deltaT[j])) { sum += deltaT[j]; cnt++; }
|
||||||
@@ -679,6 +668,34 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
return timeArray.Length - 1;
|
return timeArray.Length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ExportMeasurementCsv(string path, double[] time, double[] ustd, double[] upt, double[] deltaT, int fitStart, int fitEnd)
|
||||||
|
{
|
||||||
|
using var sw = new StreamWriter(path, false, Encoding.UTF8);
|
||||||
|
sw.WriteLine("index,time,U_std,U_pt,deltaT,fitWindow");
|
||||||
|
int n = Math.Min(Math.Min(time.Length, ustd.Length), deltaT.Length);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
bool inFit = (i >= fitStart && i <= fitEnd);
|
||||||
|
sw.WriteLine($"{i},{time[i]:F6},{ustd[i]:F6},{upt[i]:F6},{(double.IsNaN(deltaT[i]) ? 0 : deltaT[i]):F6},{(inFit ? 1 : 0)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExportCandidateWindowsCsv(string path, double[] time, double[] deltaT, int startIdx, int endIdx)
|
||||||
|
{
|
||||||
|
using var sw = new StreamWriter(path, false, Encoding.UTF8);
|
||||||
|
sw.WriteLine("s,e,t_start,t_end,meanDelta");
|
||||||
|
int n = time.Length;
|
||||||
|
int minPts = 10;
|
||||||
|
for (int s = startIdx; s <= endIdx - minPts; s++)
|
||||||
|
{
|
||||||
|
for (int e = s + minPts - 1; e <= endIdx; e++)
|
||||||
|
{
|
||||||
|
double mean = deltaT.Skip(s).Take(e - s + 1).Where(x => !double.IsNaN(x)).DefaultIfEmpty(0).Average();
|
||||||
|
sw.WriteLine($"{s},{e},{time[s]:F6},{time[e]:F6},{mean:F6}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///// <summary>
|
///// <summary>
|
||||||
///// 最小二乘法拟合斜率 (X轴为横坐标,Y轴为纵坐标) — 用于加热段 ln(t) vs ΔT
|
///// 最小二乘法拟合斜率 (X轴为横坐标,Y轴为纵坐标) — 用于加热段 ln(t) vs ΔT
|
||||||
///// </summary>
|
///// </summary>
|
||||||
@@ -782,18 +799,6 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
AverageVolumetricHeatCapacity = Measurements.Average(m => m.VolumetricHeatCapacity);
|
AverageVolumetricHeatCapacity = Measurements.Average(m => m.VolumetricHeatCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[RelayCommand]
|
|
||||||
//private void Reset()
|
|
||||||
//{
|
|
||||||
// //Measurements.Clear();
|
|
||||||
// //AverageThermalConductivity = AverageThermalDiffusivity = AverageVolumetricHeatCapacity = 0;
|
|
||||||
// //CurrentMeasurementIndex = 0;
|
|
||||||
// //StatusMessage = "已重置";
|
|
||||||
// //TestDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
||||||
// //TemperatureCurveModel = null;
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void Reset()
|
private void Reset()
|
||||||
{
|
{
|
||||||
@@ -802,20 +807,43 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
CurrentMeasurementIndex = 0;
|
CurrentMeasurementIndex = 0;
|
||||||
StatusMessage = "已重置";
|
StatusMessage = "已重置";
|
||||||
TestDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
TestDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
TemperatureCurveModel = null;
|
||||||
// 清空曲线:新建一个空白的 PlotModel 替换原来的
|
|
||||||
TemperatureCurveModel = new PlotModel
|
|
||||||
{
|
|
||||||
Title = "温升与冷却曲线",
|
|
||||||
Background = OxyColors.White
|
|
||||||
};
|
|
||||||
TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "时间 (s)" });
|
|
||||||
TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "温升 (℃)" });
|
|
||||||
TemperatureCurveModel.InvalidatePlot(true);
|
|
||||||
|
|
||||||
CurveTitle = "温升曲线";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[RelayCommand]
|
||||||
|
//private async Task GenerateReportAsync()
|
||||||
|
//{
|
||||||
|
// if (Measurements.Count == 0)
|
||||||
|
// {
|
||||||
|
// MessageBox.Show("没有测试数据", "提示");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// var extraParams = new Dictionary<string, object>
|
||||||
|
// {
|
||||||
|
// ["SampleVolume"] = SampleVolume,
|
||||||
|
// ["BubbleRemoved"] = BubbleRemoved,
|
||||||
|
// ["UsePressure"] = UsePressure,
|
||||||
|
// ["PressureValue"] = PressureValue,
|
||||||
|
// ["IsCleanConfirmed"] = IsCleanConfirmed,
|
||||||
|
// ["CleanerName"] = CleanerName,
|
||||||
|
// ["AmbientTemperature"] = AmbientTemperature,
|
||||||
|
// ["AmbientCalibrated"] = AmbientCalibrated,
|
||||||
|
// ["PlatinumCompatible"] = PlatinumCompatible,
|
||||||
|
// ["LiquidReactivityNote"] = LiquidReactivityNote,
|
||||||
|
// ["InitialResistance"] = PlatinumResistance
|
||||||
|
// };
|
||||||
|
// string reportPath = await _reportService.GenerateReportAsync(SampleId, TestTemperature, Measurements.ToList(),
|
||||||
|
// AverageThermalConductivity, AverageThermalDiffusivity, AverageVolumetricHeatCapacity,
|
||||||
|
// _config.TestParameters, extraParams);
|
||||||
|
// MessageBox.Show($"报告已生成: {reportPath}", "成功");
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// MessageBox.Show($"生成报告失败: {ex.Message}", "错误");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task GenerateReportAsync()
|
private async Task GenerateReportAsync()
|
||||||
{
|
{
|
||||||
@@ -839,23 +867,8 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 先在 UI 线程导出曲线图为字节数组
|
// 生成 PDF
|
||||||
byte[] chartImageBytes = null;
|
await Task.Run(() => GeneratePdfReport(pdfPath));
|
||||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
if (TemperatureCurveModel != null && TemperatureCurveModel.Series.Count > 0)
|
|
||||||
{
|
|
||||||
using (var stream = new MemoryStream())
|
|
||||||
{
|
|
||||||
var exporter = new PngExporter { Width = 600, Height = 400 };
|
|
||||||
exporter.Export(TemperatureCurveModel, stream);
|
|
||||||
chartImageBytes = stream.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 然后在后台线程生成 PDF(避免阻塞 UI)
|
|
||||||
await Task.Run(() => GeneratePdfReport(pdfPath, chartImageBytes));
|
|
||||||
MessageBox.Show($"报表已生成: {pdfPath}", "成功");
|
MessageBox.Show($"报表已生成: {pdfPath}", "成功");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -867,134 +880,103 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void GeneratePdfReport(string filePath, byte[] chartImageBytes)
|
private void GeneratePdfReport(string filePath)
|
||||||
{
|
{
|
||||||
|
// 1. 创建文档
|
||||||
using (var document = new PdfDocument())
|
using (var document = new PdfDocument())
|
||||||
{
|
{
|
||||||
// 创建第一个页面
|
// 2. 添加页面
|
||||||
var page = document.AddPage();
|
var page = document.AddPage();
|
||||||
page.Width = XUnit.FromMillimeter(210);
|
page.Width = XUnit.FromMillimeter(210);
|
||||||
page.Height = XUnit.FromMillimeter(297);
|
page.Height = XUnit.FromMillimeter(297);
|
||||||
var gfx = XGraphics.FromPdfPage(page);
|
|
||||||
|
|
||||||
var titleFont = new XFont("SimHei", 16, XFontStyle.Bold);
|
// 3. 开始绘制
|
||||||
var headerFont = new XFont("SimHei", 12, XFontStyle.Bold);
|
using (var gfx = XGraphics.FromPdfPage(page))
|
||||||
var normalFont = new XFont("SimHei", 10, XFontStyle.Regular);
|
|
||||||
double yPosition = 30;
|
|
||||||
|
|
||||||
// 标题
|
|
||||||
gfx.DrawString("ASTM D7896-19 瞬态热线法测试报告", titleFont, XBrushes.Black,
|
|
||||||
new XRect(0, yPosition, page.Width, 30), XStringFormats.TopCenter);
|
|
||||||
yPosition += 40;
|
|
||||||
|
|
||||||
// 基础信息(只显示一次)
|
|
||||||
gfx.DrawString($"样品名称: {SampleId}", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"测试温度: {TestTemperature:F1} °C", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"测试时间: {TestDateTime}", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"样品体积: {SampleVolume:F1} mL", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"样品密度: {SampleDensity:F0} kg/m^3", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"环境温度: {AmbientTemperature:F1} °C", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"铂丝电阻温度系数: {AlphaPt:F4} /°C", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"铂丝长度: {_config.TestParameters.PlatinumWireLength:F3} m", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 22;
|
|
||||||
gfx.DrawString($"铂丝直径: {_config.TestParameters.PlatinumWireDiameter * 1000:F2} mm", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 35;
|
|
||||||
|
|
||||||
// 曲线图(如果有)
|
|
||||||
if (chartImageBytes != null)
|
|
||||||
{
|
{
|
||||||
using (var imgStream = new MemoryStream(chartImageBytes))
|
// 创建字体
|
||||||
|
var titleFont = new XFont("Verdana", 16, XFontStyle.Bold);
|
||||||
|
var headerFont = new XFont("Verdana", 12, XFontStyle.Bold);
|
||||||
|
var normalFont = new XFont("Verdana", 10, XFontStyle.Regular);
|
||||||
|
double yPosition = 30;
|
||||||
|
|
||||||
|
// ---------- 4. 添加标题 ----------
|
||||||
|
gfx.DrawString("ASTM D7896-19 瞬态热线法测试报告", titleFont, XBrushes.Black,
|
||||||
|
new XRect(0, yPosition, page.Width, 30), XStringFormats.TopCenter);
|
||||||
|
yPosition += 40;
|
||||||
|
|
||||||
|
// ---------- 5. 添加基础信息 ----------
|
||||||
|
gfx.DrawString($"样品名称: {SampleId}", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 25;
|
||||||
|
gfx.DrawString($"测试温度: {TestTemperature:F1} °C", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 25;
|
||||||
|
// ... 所有需要显示的基础信息
|
||||||
|
|
||||||
|
yPosition += 10;
|
||||||
|
|
||||||
|
// ---------- 6. 插入温升曲线图 ----------
|
||||||
|
if (TemperatureCurveModel != null)
|
||||||
{
|
{
|
||||||
var image = XImage.FromStream(() => new MemoryStream(imgStream.ToArray()));
|
using (var stream = new MemoryStream())
|
||||||
gfx.DrawImage(image, 40, yPosition, 500, 330);
|
{
|
||||||
yPosition += 350;
|
var exporter = new PngExporter { Width = 600, Height = 400 };
|
||||||
|
exporter.Export(TemperatureCurveModel, stream);
|
||||||
|
stream.Position = 0;
|
||||||
|
var imgStream = new MemoryStream(stream.ToArray(), 0, (int)stream.Length, false, true);
|
||||||
|
var image = XImage.FromStream(() => imgStream);
|
||||||
|
gfx.DrawImage(image, 40, yPosition, 500, 330);
|
||||||
|
yPosition += 350;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 表格标题
|
// ---------- 7. 创建表格 ----------
|
||||||
gfx.DrawString("测量结果明细", headerFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 25;
|
gfx.DrawString("测量结果明细", headerFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 25;
|
||||||
|
|
||||||
// 表头(已替换特殊符号)
|
// 表头
|
||||||
string[] headers = { "序号", "热导率λ(W/(m.K))", "热扩散率α(10^-7 m^2/s)", "体积热容VHC(kJ/(m^3.K))", "比热容Cp(J/(kg.K))" };
|
string[] headers = { "序号", "热导率λ(W/(m·K))", "热扩散率α(10⁻⁷ m²/s)", "体积热容VHC(kJ/(m³·K))", "比热容Cp(J/(kg·K))" };
|
||||||
double[] colWidths = { 50, 115, 125, 125, 125 };
|
double[] colWidths = { 50, 100, 100, 120, 100 };
|
||||||
double startX = 40;
|
double startX = 40;
|
||||||
|
double currentRowY = yPosition;
|
||||||
|
|
||||||
// 辅助函数:绘制表头(用于新页)
|
// 绘制表头
|
||||||
void DrawHeader(XGraphics g, double y)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < headers.Length; i++)
|
for (int i = 0; i < headers.Length; i++)
|
||||||
{
|
{
|
||||||
double cellX = startX + colWidths.Take(i).Sum();
|
double cellX = startX + colWidths.Take(i).Sum();
|
||||||
g.DrawRectangle(XPens.Black, cellX, y, colWidths[i], 20);
|
gfx.DrawRectangle(XPens.Black, cellX, currentRowY, colWidths[i], 20);
|
||||||
var textRect = new XRect(cellX, y, colWidths[i], 20);
|
var textRect = new XRect(cellX, currentRowY, colWidths[i], 20);
|
||||||
g.DrawString(headers[i], normalFont, XBrushes.Black, textRect, XStringFormats.Center);
|
gfx.DrawString(headers[i], normalFont, XBrushes.Black, textRect, XStringFormats.Center);
|
||||||
}
|
}
|
||||||
}
|
currentRowY += 20;
|
||||||
|
|
||||||
// 绘制第一页的表头
|
// 填充数据行 (假设 Measurements 是列表)
|
||||||
DrawHeader(gfx, yPosition);
|
for (int i = 0; i < Measurements.Count; i++)
|
||||||
double currentRowY = yPosition + 20; // 表头高度20
|
|
||||||
const double rowHeight = 20;
|
|
||||||
const double bottomMargin = 50; // 页面底部留白
|
|
||||||
|
|
||||||
// 遍历所有测量数据
|
|
||||||
foreach (var m in Measurements)
|
|
||||||
{
|
|
||||||
// 检查是否需要换页
|
|
||||||
if (currentRowY + rowHeight > page.Height - bottomMargin)
|
|
||||||
{
|
{
|
||||||
gfx.Dispose();
|
var m = Measurements[i];
|
||||||
page = document.AddPage();
|
string[] rowData = {
|
||||||
page.Width = XUnit.FromMillimeter(210);
|
m.Index.ToString(),
|
||||||
page.Height = XUnit.FromMillimeter(297);
|
m.ThermalConductivity.ToString("F6"),
|
||||||
gfx = XGraphics.FromPdfPage(page);
|
(m.ThermalDiffusivity * 1e7).ToString("F3"),
|
||||||
gfx.DrawString("ASTM D7896-19 瞬态热线法测试报告(续)", headerFont, XBrushes.Black,
|
m.VolumetricHeatCapacity.ToString("F2"),
|
||||||
new XRect(0, 30, page.Width, 30), XStringFormats.TopCenter);
|
m.SpecificHeatCapacity.ToString("F2")
|
||||||
currentRowY = 80;
|
};
|
||||||
DrawHeader(gfx, currentRowY - 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] rowData = {
|
for (int j = 0; j < rowData.Length; j++)
|
||||||
m.Index.ToString(),
|
{
|
||||||
m.ThermalConductivity.ToString("F6"),
|
double cellX = startX + colWidths.Take(j).Sum();
|
||||||
(m.ThermalDiffusivity * 1e7).ToString("F3"),
|
gfx.DrawRectangle(XPens.Black, cellX, currentRowY, colWidths[j], 20);
|
||||||
m.VolumetricHeatCapacity.ToString("F2"),
|
var textRect = new XRect(cellX, currentRowY, colWidths[j], 20);
|
||||||
m.SpecificHeatCapacity.ToString("F2")
|
gfx.DrawString(rowData[j], normalFont, XBrushes.Black, textRect, XStringFormats.Center);
|
||||||
};
|
}
|
||||||
for (int j = 0; j < rowData.Length; j++)
|
currentRowY += 20;
|
||||||
{
|
|
||||||
double cellX = startX + colWidths.Take(j).Sum();
|
|
||||||
gfx.DrawRectangle(XPens.Black, cellX, currentRowY, colWidths[j], rowHeight);
|
|
||||||
var textRect = new XRect(cellX, currentRowY, colWidths[j], rowHeight);
|
|
||||||
gfx.DrawString(rowData[j], normalFont, XBrushes.Black, textRect, XStringFormats.Center);
|
|
||||||
}
|
}
|
||||||
currentRowY += rowHeight;
|
yPosition = currentRowY + 10;
|
||||||
|
|
||||||
|
// ---------- 8. 添加平均值 ----------
|
||||||
|
gfx.DrawString($"平均热导率: {AverageThermalConductivity:F6} W/(m·K)", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 20;
|
||||||
|
// ... 其他平均值
|
||||||
|
|
||||||
|
// ---------- 9. 添加生成时间和页脚 ----------
|
||||||
|
gfx.DrawString($"生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}", normalFont, XBrushes.Black, new XPoint(40, page.Height - 30));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加空行,避免平均值与表格重叠
|
// 10. 保存文档
|
||||||
currentRowY += 60;
|
|
||||||
|
|
||||||
// 检查是否需要换页(平均值部分)
|
|
||||||
if (currentRowY + 80 > page.Height - bottomMargin)
|
|
||||||
{
|
|
||||||
gfx.Dispose();
|
|
||||||
page = document.AddPage();
|
|
||||||
page.Width = XUnit.FromMillimeter(210);
|
|
||||||
page.Height = XUnit.FromMillimeter(297);
|
|
||||||
gfx = XGraphics.FromPdfPage(page);
|
|
||||||
currentRowY = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 平均值(单位已替换)
|
|
||||||
gfx.DrawString($"平均热导率: {AverageThermalConductivity:F6} W/(m.K)", normalFont, XBrushes.Black, new XPoint(40, currentRowY)); currentRowY += 20;
|
|
||||||
gfx.DrawString($"平均热扩散率: {AverageThermalDiffusivity:E6} m^2/s", normalFont, XBrushes.Black, new XPoint(40, currentRowY)); currentRowY += 20;
|
|
||||||
gfx.DrawString($"平均体积热容: {AverageVolumetricHeatCapacity:F2} kJ/(m^3.K)", normalFont, XBrushes.Black, new XPoint(40, currentRowY)); currentRowY += 20;
|
|
||||||
// 比热容转换:VHC 单位 kJ/(m^3.K) 先转为 J/(m^3.K) 再除以密度得到 J/(kg.K)
|
|
||||||
double avgCp_J_per_kgK = (AverageVolumetricHeatCapacity * 1000) / SampleDensity;
|
|
||||||
gfx.DrawString($"平均比热容: {avgCp_J_per_kgK:F0} J/(kg.K)", normalFont, XBrushes.Black, new XPoint(40, currentRowY)); currentRowY += 40;
|
|
||||||
|
|
||||||
// 页脚
|
|
||||||
gfx.DrawString($"生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}", normalFont, XBrushes.Black, new XPoint(40, page.Height - 30));
|
|
||||||
gfx.Dispose();
|
|
||||||
|
|
||||||
document.Save(filePath);
|
document.Save(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1067,150 +1049,8 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
float rawPressure = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Pressure);
|
float rawPressure = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Pressure);
|
||||||
ChamberPressure = rawPressure / 10.0;
|
ChamberPressure = rawPressure;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
private SerialPort _serialPort;
|
|
||||||
private bool _isConnected = false;
|
|
||||||
|
|
||||||
private async Task initPort()
|
|
||||||
{
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string port = "COM10";
|
|
||||||
int baud = 19200;
|
|
||||||
_serialPort = new SerialPort(port, baud, Parity.None, 8, StopBits.One);
|
|
||||||
_serialPort.ReadTimeout = 1000; // 关键:避免永久阻塞
|
|
||||||
_serialPort.WriteTimeout = 1000;
|
|
||||||
_serialPort.Open();
|
|
||||||
|
|
||||||
_isConnected = true;
|
|
||||||
|
|
||||||
|
|
||||||
// 发送配置命令(不输出电流,只设置模式),同样异步等待但不死锁
|
|
||||||
await ConfigureOptimalMode();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"连接失败: {ex.Message}");
|
|
||||||
_isConnected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ConfigureOptimalMode()
|
|
||||||
{
|
|
||||||
// 构造命令:电流 0,但强制 PC 模式和跟踪模式
|
|
||||||
byte[] configCmd = new byte[12];
|
|
||||||
configCmd[0] = 0xFE;
|
|
||||||
configCmd[1] = 0xFE;
|
|
||||||
configCmd[2] = 0x55; // 识别码高
|
|
||||||
configCmd[3] = 0xAA; // 识别码低
|
|
||||||
configCmd[4] = 0x00; // 电流高字节 (0A)
|
|
||||||
configCmd[5] = 0x00; // 电流低字节
|
|
||||||
configCmd[6] = 0x01; // PC调节模式
|
|
||||||
configCmd[7] = 0x01;
|
|
||||||
configCmd[8] = 0x00; // 开启跟踪模式
|
|
||||||
configCmd[9] = 0x00;
|
|
||||||
configCmd[10] = 0xFF;
|
|
||||||
configCmd[11] = 0xFF;
|
|
||||||
|
|
||||||
await SendCommandSafe(configCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 安全的命令发送(异步读取,不卡UI)
|
|
||||||
private async Task<bool> SendCommandSafe(byte[] command)
|
|
||||||
{
|
|
||||||
if (!_isConnected || _serialPort == null || !_serialPort.IsOpen)
|
|
||||||
{
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 清空缓冲区
|
|
||||||
_serialPort.DiscardInBuffer();
|
|
||||||
_serialPort.DiscardOutBuffer();
|
|
||||||
|
|
||||||
// 发送命令
|
|
||||||
await _serialPort.BaseStream.WriteAsync(command, 0, command.Length);
|
|
||||||
|
|
||||||
|
|
||||||
// 异步读取12字节(带超时)
|
|
||||||
byte[] buffer = new byte[12];
|
|
||||||
int totalRead = 0;
|
|
||||||
DateTime start = DateTime.Now;
|
|
||||||
while (totalRead < 12 && (DateTime.Now - start).TotalMilliseconds < 1500)
|
|
||||||
{
|
|
||||||
if (_serialPort.BytesToRead > 0)
|
|
||||||
{
|
|
||||||
int read = await _serialPort.BaseStream.ReadAsync(buffer, totalRead, 12 - totalRead);
|
|
||||||
if (read > 0) totalRead += read;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
await Task.Delay(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalRead == 12)
|
|
||||||
{
|
|
||||||
|
|
||||||
// 解析回采电流 (byte4, byte5)
|
|
||||||
int rawCurrent = (buffer[4] << 8) | buffer[5];
|
|
||||||
double actualCurrent = rawCurrent / 1000.0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async void BtnSet()
|
|
||||||
{
|
|
||||||
if (!_isConnected)
|
|
||||||
{
|
|
||||||
MessageBox.Show("请先连接串口");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
double target = 0.650;
|
|
||||||
|
|
||||||
// 构造12字节电流命令
|
|
||||||
int raw = (int)(target * 1000);
|
|
||||||
byte cmdH = (byte)((raw >> 8) & 0xFF);
|
|
||||||
byte cmdL = (byte)(raw & 0xFF);
|
|
||||||
|
|
||||||
byte[] currentCmd = new byte[12];
|
|
||||||
currentCmd[0] = 0xFE;
|
|
||||||
currentCmd[1] = 0xFE;
|
|
||||||
currentCmd[2] = 0x55;
|
|
||||||
currentCmd[3] = 0xAA;
|
|
||||||
currentCmd[4] = cmdH;
|
|
||||||
currentCmd[5] = cmdL;
|
|
||||||
currentCmd[6] = 0x01;
|
|
||||||
currentCmd[7] = 1;
|
|
||||||
currentCmd[8] = 0;
|
|
||||||
currentCmd[9] = 0x00;
|
|
||||||
currentCmd[10] = 0xFF;
|
|
||||||
currentCmd[11] = 0xFF;
|
|
||||||
|
|
||||||
await SendCommandSafe(currentCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -134,9 +134,9 @@
|
|||||||
<CheckBox IsChecked="{Binding IsCleanConfirmed}" Content="采样池清洁 (7.1)" Margin="0,0,15,0"/>
|
<CheckBox IsChecked="{Binding IsCleanConfirmed}" Content="采样池清洁 (7.1)" Margin="0,0,15,0"/>
|
||||||
<CheckBox IsChecked="{Binding BubbleRemoved}" Content="气泡清除 (7.6)" Margin="0,0,15,0"/>
|
<CheckBox IsChecked="{Binding BubbleRemoved}" Content="气泡清除 (7.6)" Margin="0,0,15,0"/>
|
||||||
<CheckBox IsChecked="{Binding PlatinumCompatible}" Content="铂兼容性 (1.4)" Margin="0,0,15,0"/>
|
<CheckBox IsChecked="{Binding PlatinumCompatible}" Content="铂兼容性 (1.4)" Margin="0,0,15,0"/>
|
||||||
<CheckBox IsChecked="{Binding AmbientCalibrated}" Content="采样池温度校准 (8.1)" Margin="0,0,15,0"/>
|
<CheckBox IsChecked="{Binding AmbientCalibrated}" Content="环境温度校准 (8.1)" Margin="0,0,15,0"/>
|
||||||
<TextBlock Text="状态:" VerticalAlignment="Center" Margin="20,0,5,0"/>
|
<TextBlock Text="状态:" VerticalAlignment="Center" Margin="20,0,5,0"/>
|
||||||
<TextBox Text="{Binding StatusMessage}" Width="200" IsReadOnly="True" Background="#FFF7E6"/>
|
<TextBox Text="{Binding StatusMessage}" Width="260" IsReadOnly="True" Background="#FFF7E6"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
@@ -319,21 +319,19 @@
|
|||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 7. 系统校准(可选,可收起到折叠区域,为节省空间放在底部) -->
|
<!-- 7. 系统校准(可选,可收起到折叠区域,为节省空间放在底部) -->
|
||||||
<!--<Border Grid.Row="6" Background="White" CornerRadius="6" Padding="8" Margin="0,5" Effect="{StaticResource CardShadow}">
|
<Border Grid.Row="6" Background="White" CornerRadius="6" Padding="8" Margin="0,5" Effect="{StaticResource CardShadow}">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock Text="系统校准 (附录A3)" FontWeight="Bold" Margin="0,0,0,5"/>
|
<TextBlock Text="系统校准 (附录A3)" FontWeight="Bold" Margin="0,0,0,5"/>
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<TextBlock Text="参考液:" VerticalAlignment="Center"/>
|
<TextBlock Text="参考液:" VerticalAlignment="Center"/>
|
||||||
<ComboBox ItemsSource="{Binding ReferenceLiquids}" SelectedItem="{Binding SelectedReferenceLiquid}" Width="100" Margin="5,0"/>
|
<ComboBox ItemsSource="{Binding ReferenceLiquids}" IsReadOnly="True" SelectedItem="{Binding SelectedReferenceLiquid}" Width="100" Margin="5,0"/>
|
||||||
<TextBlock Text="参考热导率 (W/m·K):" VerticalAlignment="Center" Margin="10,0,5,0"/>
|
<TextBlock Text="参考热导率 (W/m·K):" VerticalAlignment="Center" Margin="10,0,5,0"/>
|
||||||
<TextBox Text="{Binding ReferenceConductivity}" Width="70" Margin="0,0,10,0"/>
|
<TextBox Text="{Binding ReferenceConductivity}" Width="70" Margin="0,0,10,0"/>
|
||||||
-->
|
<!--<Button Content="开始校准" Command="{Binding PerformSystemCalibrationCommand}" Width="100"/>-->
|
||||||
<!--<Button Content="开始校准" Command="{Binding PerformSystemCalibrationCommand}" Width="100"/>-->
|
|
||||||
<!--
|
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<TextBlock Text="{Binding CalibrationStatus}" FontSize="11" Foreground="Blue" Margin="0,5,0,0"/>
|
<TextBlock Text="{Binding CalibrationStatus}" FontSize="11" Foreground="Blue" Margin="0,5,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>-->
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
BIN
瞬态热线法说明书.docx
BIN
瞬态热线法说明书.docx
Binary file not shown.
Reference in New Issue
Block a user