20260313 客户需求整改

This commit is contained in:
GukSang.Jin
2026-03-13 10:42:41 +08:00
parent 5ba7094709
commit dced00183d
8 changed files with 310 additions and 31 deletions

View File

@@ -107,7 +107,9 @@ namespace CSI_H238M
// 保存配置(如果需要)
try
{
_config?.Save(AppConfig.GetDefaultConfigPath());
string configPath = AppConfig.GetDefaultConfigPath();
_config = AppConfig.Load(configPath);
_config?.Save(configPath);
}
catch
{

View File

@@ -42,6 +42,8 @@ namespace COFTester.Models
/// </summary>
public string Language { get; set; } = "zh-CN";
public string ForceDisplayUnit { get; set; } = "N";
/// <summary>
/// 自動保存測試結果
/// </summary>

View File

@@ -240,8 +240,10 @@ namespace COFTester.Models
/// </summary>
public class TestResult : INotifyPropertyChanged
{
private const double StandardGravity = 9.80665;
private bool _isVisible = true;
private string _sampleNumber = string.Empty;
private string _forceDisplayUnit = "N";
public Guid TestId { get; set; } = Guid.NewGuid(); // 測試唯一ID
public DateTime TestDateTime { get; set; } = DateTime.Now; // 測試時間
@@ -267,6 +269,31 @@ namespace COFTester.Models
/// <summary>
/// 试样编号
/// </summary>
public string ForceDisplayUnit
{
get => _forceDisplayUnit;
set
{
string normalizedUnit = string.Equals(value, "g", StringComparison.OrdinalIgnoreCase) ? "g" : "N";
if (_forceDisplayUnit == normalizedUnit)
{
return;
}
_forceDisplayUnit = normalizedUnit;
OnPropertyChanged();
OnPropertyChanged(nameof(DisplayedMaxForce));
OnPropertyChanged(nameof(DisplayedAvgKineticForce));
OnPropertyChanged(nameof(DisplayedPeelStrength25mm));
}
}
public double DisplayedMaxForce => ConvertForceForDisplay(MaxForce);
public double DisplayedAvgKineticForce => ConvertForceForDisplay(AvgKineticForce);
public double DisplayedPeelStrength25mm => ConvertForceForDisplay(PeelStrength_N_25mm);
public string SampleNumber
{
get => _sampleNumber;
@@ -282,6 +309,13 @@ namespace COFTester.Models
set { _isVisible = value; OnPropertyChanged(); }
}
private double ConvertForceForDisplay(double forceInNewton)
{
return ForceDisplayUnit == "g"
? forceInNewton * 1000.0 / StandardGravity
: forceInNewton;
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{

View File

@@ -166,6 +166,7 @@ namespace COFTester.Services
/// </summary>
public class PdfReportService
{
private const double StandardGravity = 9.80665;
private const double PageWidth = 595; // A4宽度
private const double PageHeight = 842; // A4高度
private const double MarginLeft = 50;
@@ -195,10 +196,11 @@ namespace COFTester.Services
/// <param name="testRecords">测试记录</param>
/// <param name="parameters">测试参数</param>
/// <param name="isChinese">是否使用中文(默认根据当前语言)</param>
public void GenerateReport(string filePath, IEnumerable<TestResult> testRecords, TestParameters parameters, bool? isChinese = null)
public void GenerateReport(string filePath, IEnumerable<TestResult> testRecords, TestParameters parameters, string forceDisplayUnit = "N", bool? isChinese = null)
{
// 如果未指定语言,根据当前语言资源判断
bool useChinese = isChinese ?? (Resources.LanguageResources.Instance.CurrentLanguage == "zh-CN");
string normalizedForceUnit = NormalizeForceDisplayUnit(forceDisplayUnit);
if (testRecords == null || !testRecords.Any())
throw new ArgumentException(useChinese ? "测试记录不能为空" : "Test records cannot be empty");
@@ -232,13 +234,13 @@ namespace COFTester.Services
yPosition = DrawHeader(gfx, yPosition, useChinese);
System.Diagnostics.Debug.WriteLine("标题已绘制");
yPosition = DrawTestInfo(gfx, yPosition, parameters, useChinese);
yPosition = DrawTestInfo(gfx, yPosition, parameters, normalizedForceUnit, useChinese);
System.Diagnostics.Debug.WriteLine("测试信息已绘制");
yPosition = DrawStatistics(gfx, yPosition, testRecords, useChinese);
System.Diagnostics.Debug.WriteLine("统计信息已绘制");
yPosition = DrawDetailedResults(gfx, yPosition, testRecords, document, gfx, page, useChinese);
yPosition = DrawDetailedResults(gfx, yPosition, testRecords, normalizedForceUnit, document, gfx, page, useChinese);
System.Diagnostics.Debug.WriteLine("详细结果已绘制");
// 保存文档
@@ -283,7 +285,7 @@ namespace COFTester.Services
/// <summary>
/// 绘制测试信息
/// </summary>
private double DrawTestInfo(XGraphics gfx, double yPosition, TestParameters parameters, bool isChinese)
private double DrawTestInfo(XGraphics gfx, double yPosition, TestParameters parameters, string forceDisplayUnit, bool isChinese)
{
string fontFamily = GetFontFamily(isChinese);
XFont sectionFont = new XFont(fontFamily, 14, XFontStyleEx.Bold);
@@ -299,6 +301,7 @@ namespace COFTester.Services
{
$"测试标准: {parameters.Standard}",
$"滑块质量: {parameters.SledMass:F1} g",
$"力值单位: {forceDisplayUnit}",
$"测试速度: {parameters.TestSpeed:F1} mm/min",
$"测试行程: {parameters.TestStroke:F1} mm",
$"操作员: {parameters.Operator}"
@@ -306,6 +309,7 @@ namespace COFTester.Services
{
$"Test Standard: {parameters.Standard}",
$"Sled Mass: {parameters.SledMass:F1} g",
$"Force Unit: {forceDisplayUnit}",
$"Test Speed: {parameters.TestSpeed:F1} mm/min",
$"Test Stroke: {parameters.TestStroke:F1} mm",
$"Operator: {parameters.Operator}"
@@ -403,7 +407,7 @@ namespace COFTester.Services
/// 绘制详细测试结果
/// </summary>
private double DrawDetailedResults(XGraphics gfx, double yPosition, IEnumerable<TestResult> testRecords,
PdfDocument document, XGraphics currentGfx, PdfPage currentPage, bool isChinese)
string forceDisplayUnit, PdfDocument document, XGraphics currentGfx, PdfPage currentPage, bool isChinese)
{
string fontFamily = GetFontFamily(isChinese);
XFont sectionFont = new XFont(fontFamily, 14, XFontStyleEx.Bold);
@@ -434,8 +438,8 @@ namespace COFTester.Services
// 表头
string[] headers = isChinese ?
new[] { "编号", "测试时间", "静摩擦", "动摩擦", "最大力", "平均力" } :
new[] { "No.", "Test Time", "Static", "Kinetic", "Max F", "Avg F" };
new[] { "编号", "测试时间", "静摩擦", "动摩擦", $"最大力({forceDisplayUnit})", $"平均力({forceDisplayUnit})" } :
new[] { "No.", "Test Time", "Static", "Kinetic", $"Max F ({forceDisplayUnit})", $"Avg F ({forceDisplayUnit})" };
double currentX = tableX;
for (int i = 0; i < headers.Length; i++)
@@ -474,8 +478,8 @@ namespace COFTester.Services
record.TestDateTime.ToString("MM-dd HH:mm"),
record.StaticCOF.ToString("F4"),
record.KineticCOF.ToString("F4"),
record.MaxForce.ToString("F2") + " N",
record.AvgKineticForce.ToString("F2") + " N"
ConvertForceForDisplay(record.MaxForce, forceDisplayUnit).ToString("F2") + " " + forceDisplayUnit,
ConvertForceForDisplay(record.AvgKineticForce, forceDisplayUnit).ToString("F2") + " " + forceDisplayUnit
};
for (int i = 0; i < rowData.Length; i++)
@@ -556,6 +560,18 @@ namespace COFTester.Services
XStringFormats.TopCenter);
}
private static string NormalizeForceDisplayUnit(string? unit)
{
return string.Equals(unit, "g", StringComparison.OrdinalIgnoreCase) ? "g" : "N";
}
private static double ConvertForceForDisplay(double forceInNewton, string forceDisplayUnit)
{
return NormalizeForceDisplayUnit(forceDisplayUnit) == "g"
? forceInNewton * 1000.0 / StandardGravity
: forceInNewton;
}
/// <summary>
/// 计算标准差
/// </summary>

View File

@@ -9,6 +9,7 @@ using System.Windows.Threading;
using System.Windows;
using System.Threading.Tasks;
using System.Threading;
using System.Globalization;
using COFTester.Models;
using COFTester.Services;
using COFTester.Resources;
@@ -33,6 +34,7 @@ namespace COFTester.ViewModels
private bool _isUiDataUpdateQueued;
private long _lastPlotRefreshTick;
private const int PlotRefreshIntervalMs = 100;
private const double StandardGravity = 9.80665;
private double _currentForce;
private double _currentDisp;
@@ -52,6 +54,8 @@ namespace COFTester.ViewModels
private bool _stopRequestedByUser = false;
private bool _acceptIncomingTestData = false;
private int _testSessionId = 0;
private string _selectedSledMassPreset = "200";
private string _forceDisplayUnit = "N";
private string _selectedDirection = ""; // 选中的方向Up/Down/Right/Left
private string _resetButtonText; // 复位按钮文本
private string _testButtonText; // 测试按钮文本
@@ -100,6 +104,9 @@ namespace COFTester.ViewModels
UpdateCustomParametersCommand = new AsyncRelayCommand(UpdateCustomParametersAsync, () => IsConnected && SelectedStandard == "Custom");
Parameters = _config.DefaultTestParameters ?? new TestParameters();
Parameters.PropertyChanged += OnParametersPropertyChanged;
_forceDisplayUnit = NormalizeForceDisplayUnit(_config.ForceDisplayUnit);
SyncSledMassPresetFromValue();
TestRecords = new ObservableCollection<TestResult>();
TestRecords.CollectionChanged += (s, e) =>
{
@@ -290,6 +297,69 @@ namespace COFTester.ViewModels
/// </summary>
public LanguageResources Lang => LanguageResources.Instance;
public string ForceDisplayUnit
{
get => _forceDisplayUnit;
set
{
var normalizedUnit = NormalizeForceDisplayUnit(value);
if (_forceDisplayUnit == normalizedUnit)
{
return;
}
_forceDisplayUnit = normalizedUnit;
_config.ForceDisplayUnit = normalizedUnit;
OnPropertyChanged();
NotifyForceDisplayChanged();
PersistSettings();
RefreshPlotForDisplaySettings();
}
}
public string ForceDisplayLabel =>
Lang.CurrentLanguage == "zh-CN" ? $"力值 ({ForceDisplayUnit})" : $"Force ({ForceDisplayUnit})";
public string ForceAxisLabel =>
Lang.CurrentLanguage == "zh-CN" ? $"力值 ({ForceDisplayUnit})" : $"Force ({ForceDisplayUnit})";
public string AvgPeelForceLabel =>
Lang.CurrentLanguage == "zh-CN" ? $"平均剥离力 ({ForceDisplayUnit})" : $"Avg Peel Force ({ForceDisplayUnit})";
public string PeelStrengthLabel =>
Lang.CurrentLanguage == "zh-CN" ? $"剥离强度 ({ForceDisplayUnit}/25mm)" : $"Peel Strength ({ForceDisplayUnit}/25mm)";
public string MaxForceLabel =>
Lang.CurrentLanguage == "zh-CN" ? $"最大力值 ({ForceDisplayUnit})" : $"Max Force ({ForceDisplayUnit})";
public string AvgForceDisplayLabel =>
Lang.CurrentLanguage == "zh-CN" ? $"平均力值 ({ForceDisplayUnit})" : $"Avg Force ({ForceDisplayUnit})";
public string SelectedSledMassPreset
{
get => _selectedSledMassPreset;
set
{
var normalizedPreset = string.IsNullOrWhiteSpace(value) ? "Custom" : value;
if (_selectedSledMassPreset == normalizedPreset)
{
return;
}
_selectedSledMassPreset = normalizedPreset;
OnPropertyChanged();
OnPropertyChanged(nameof(IsCustomSledMass));
if (double.TryParse(normalizedPreset, NumberStyles.Float, CultureInfo.InvariantCulture, out double presetMass))
{
Parameters.SledMass = presetMass;
PersistSettings();
}
}
}
public bool IsCustomSledMass => SelectedSledMassPreset == "Custom";
/// <summary>
/// 初始化 ScottPlot 图表
/// </summary>
@@ -310,7 +380,7 @@ namespace COFTester.ViewModels
// 设置坐标轴标签(使用已设置的中文字体)
_wpfPlot.Plot.XLabel(Lang.DisplacementAxis);
_wpfPlot.Plot.YLabel(Lang.ForceAxis);
_wpfPlot.Plot.YLabel(ForceAxisLabel);
// 设置Y轴最小值为0
_wpfPlot.Plot.Axes.SetLimitsY(0, 10);
@@ -389,7 +459,7 @@ namespace COFTester.ViewModels
else
{
var xData = _realTimePoints.Select(p => p.Displacement).ToArray();
var yData = _realTimePoints.Select(p => p.Force).ToArray();
var yData = _realTimePoints.Select(p => ConvertForceForDisplay(p.Force)).ToArray();
// 创建新的散点图
_scatterPlot = _wpfPlot.Plot.Add.Scatter(xData, yData);
@@ -509,8 +579,15 @@ namespace COFTester.ViewModels
public double CurrentForce
{
get => _currentForce;
set { _currentForce = value; OnPropertyChanged(); }
set
{
_currentForce = value;
OnPropertyChanged();
OnPropertyChanged(nameof(DisplayedCurrentForce));
}
}
public double DisplayedCurrentForce => ConvertForceForDisplay(CurrentForce);
public double CurrentDisp
{
@@ -545,8 +622,20 @@ namespace COFTester.ViewModels
public TestResult? LatestResult
{
get => _latestResult;
set { _latestResult = value; OnPropertyChanged(); }
set
{
_latestResult = value;
OnPropertyChanged();
OnPropertyChanged(nameof(DisplayedLatestAvgKineticForce));
OnPropertyChanged(nameof(DisplayedLatestPeelStrength));
}
}
public double? DisplayedLatestAvgKineticForce =>
LatestResult == null ? null : ConvertForceForDisplay(LatestResult.AvgKineticForce);
public double? DisplayedLatestPeelStrength =>
LatestResult == null ? null : ConvertForceForDisplay(LatestResult.PeelStrength_N_25mm);
public string StatusMessage
{
@@ -688,6 +777,7 @@ namespace COFTester.ViewModels
};
// 添加到测试记录集合
result.ForceDisplayUnit = ForceDisplayUnit;
TestRecords.Add(result);
LatestResult = result;
@@ -1552,7 +1642,7 @@ namespace COFTester.ViewModels
return;
var xData = result.RawData.Select(p => p.Displacement).ToArray();
var yData = result.RawData.Select(p => p.Force).ToArray();
var yData = result.RawData.Select(p => ConvertForceForDisplay(p.Force)).ToArray();
var scatter = _wpfPlot.Plot.Add.Scatter(xData, yData);
scatter.LineWidth = 2;
@@ -1656,7 +1746,7 @@ namespace COFTester.ViewModels
try
{
var pdfService = new Services.PdfReportService();
pdfService.GenerateReport(filePath, TestRecords, Parameters);
pdfService.GenerateReport(filePath, TestRecords, Parameters, ForceDisplayUnit);
}
catch (Exception ex)
{
@@ -1689,10 +1779,17 @@ namespace COFTester.ViewModels
if (_wpfPlot != null)
{
_wpfPlot.Plot.XLabel(Lang.DisplacementAxis);
_wpfPlot.Plot.YLabel(Lang.ForceAxis);
_wpfPlot.Plot.YLabel(ForceAxisLabel);
_wpfPlot.Refresh();
}
OnPropertyChanged(nameof(ForceDisplayLabel));
OnPropertyChanged(nameof(ForceAxisLabel));
OnPropertyChanged(nameof(AvgPeelForceLabel));
OnPropertyChanged(nameof(PeelStrengthLabel));
OnPropertyChanged(nameof(MaxForceLabel));
OnPropertyChanged(nameof(AvgForceDisplayLabel));
// 更新当前状态消息
if (_statusMessage == "系统就绪" || _statusMessage == "System Ready")
StatusMessage = Lang.SystemReady;
@@ -1711,6 +1808,101 @@ namespace COFTester.ViewModels
TestButtonText = Lang.StartTest;
ResetButtonText = Lang.ResetSystem;
}
PersistSettings();
}
private void OnParametersPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(TestParameters.SledMass))
{
SyncSledMassPresetFromValue();
PersistSettings();
}
}
private void SyncSledMassPresetFromValue()
{
string preset = Math.Abs(Parameters.SledMass - 200.0) < 0.0001 ? "200"
: Math.Abs(Parameters.SledMass - 300.0) < 0.0001 ? "300"
: Math.Abs(Parameters.SledMass - 500.0) < 0.0001 ? "500"
: "Custom";
if (_selectedSledMassPreset != preset)
{
_selectedSledMassPreset = preset;
OnPropertyChanged(nameof(SelectedSledMassPreset));
OnPropertyChanged(nameof(IsCustomSledMass));
}
}
private double ConvertForceForDisplay(double forceInNewton)
{
return ForceDisplayUnit == "g"
? forceInNewton * 1000.0 / StandardGravity
: forceInNewton;
}
private string NormalizeForceDisplayUnit(string? unit)
{
return string.Equals(unit, "g", StringComparison.OrdinalIgnoreCase) ? "g" : "N";
}
private void NotifyForceDisplayChanged()
{
OnPropertyChanged(nameof(DisplayedCurrentForce));
OnPropertyChanged(nameof(DisplayedLatestAvgKineticForce));
OnPropertyChanged(nameof(DisplayedLatestPeelStrength));
OnPropertyChanged(nameof(ForceDisplayLabel));
OnPropertyChanged(nameof(ForceAxisLabel));
OnPropertyChanged(nameof(AvgPeelForceLabel));
OnPropertyChanged(nameof(PeelStrengthLabel));
OnPropertyChanged(nameof(MaxForceLabel));
OnPropertyChanged(nameof(AvgForceDisplayLabel));
foreach (var record in TestRecords)
{
record.ForceDisplayUnit = ForceDisplayUnit;
}
}
private void RefreshPlotForDisplaySettings()
{
if (_wpfPlot == null)
{
return;
}
_scatterPlot = null;
_testCurves.Clear();
InitializeScottPlot();
foreach (var record in TestRecords)
{
AddCurveToPlot(record);
}
if (_realTimePoints.Count > 0)
{
UpdateScottPlot();
}
UpdateAllCurvesVisibility();
}
private void PersistSettings()
{
try
{
_config.DefaultTestParameters = Parameters;
_config.Language = Lang.CurrentLanguage;
_config.ForceDisplayUnit = ForceDisplayUnit;
_config.Save(AppConfig.GetDefaultConfigPath());
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"[ViewModel] 保存配置失败: {ex.Message}");
}
}
private void OpenConfig()
@@ -1865,6 +2057,7 @@ namespace COFTester.ViewModels
_daqService.DataReceived -= OnDataReceived;
_daqService.TestFinished -= OnTestFinished;
_daqService.ErrorOccurred -= OnErrorOccurred;
Parameters.PropertyChanged -= OnParametersPropertyChanged;
// 停止測試
if (_isTesting)

View File

@@ -69,17 +69,17 @@
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding MaxForce, StringFormat={}{0:F3}}" Width="120">
<DataGridTextColumn Binding="{Binding DisplayedMaxForce, StringFormat={}{0:F3}}" Width="120">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.Lang.MaxForce, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<TextBlock Text="{Binding DataContext.MaxForceLabel, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding AvgKineticForce, StringFormat={}{0:F3}}" Width="120">
<DataGridTextColumn Binding="{Binding DisplayedAvgKineticForce, StringFormat={}{0:F3}}" Width="120">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.Lang.AvgForce, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<TextBlock Text="{Binding DataContext.AvgForceDisplayLabel, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>

View File

@@ -53,17 +53,49 @@
</Grid>
<!-- 质量选择 -->
<TextBlock Text="滑块质量" Margin="0,10,0,5" FontSize="13" Foreground="{StaticResource GrayBrush}"/>
<ComboBox SelectedValue="{Binding Parameters.SledMass, Mode=TwoWay}"
<TextBlock Text="滑块质量预设" Margin="0,10,0,5" FontSize="13" Foreground="{StaticResource GrayBrush}"/>
<ComboBox SelectedValue="{Binding SelectedSledMassPreset, Mode=TwoWay}"
SelectedValuePath="Tag"
Margin="0,0,0,15"
Height="40"
FontSize="13"
VerticalContentAlignment="Center"
BorderBrush="#E0E0E0">
<ComboBoxItem Content="200 g" Tag="200" IsSelected="True"/>
<ComboBoxItem Content="200 g" Tag="200"/>
<ComboBoxItem Content="300 g" Tag="300"/>
<ComboBoxItem Content="500 g" Tag="500"/>
<ComboBoxItem Content="自定义" Tag="Custom"/>
</ComboBox>
<StackPanel Margin="0,0,0,15">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsCustomSledMass}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<TextBlock Text="自定义滑块质量 (g)" Margin="0,0,0,5" FontSize="13" Foreground="{StaticResource GrayBrush}"/>
<TextBox Text="{Binding Parameters.SledMass, StringFormat={}{0:F1}, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
Height="40"
VerticalContentAlignment="Center"
FontSize="13"
BorderBrush="#E0E0E0"/>
</StackPanel>
<TextBlock Text="力值显示单位" Margin="0,10,0,5" FontSize="13" Foreground="{StaticResource GrayBrush}"/>
<ComboBox SelectedValue="{Binding ForceDisplayUnit, Mode=TwoWay}"
SelectedValuePath="Tag"
Margin="0,0,0,15"
Height="40"
FontSize="13"
VerticalContentAlignment="Center"
BorderBrush="#E0E0E0">
<ComboBoxItem Content="N" Tag="N"/>
<ComboBoxItem Content="g" Tag="g"/>
</ComboBox>
<!-- 标准选择 -->

View File

@@ -88,13 +88,13 @@
<!-- 实时力值监控 - 工业仪表盘风格 -->
<Border Style="{StaticResource CardStyle}" Background="#0A192F">
<StackPanel>
<TextBlock Text="{Binding Lang.Force}" FontSize="14" Foreground="#BDC3C7" HorizontalAlignment="Center" Margin="0,0,0,5"/>
<TextBlock Text="{Binding ForceDisplayLabel}" FontSize="14" Foreground="#BDC3C7" HorizontalAlignment="Center" Margin="0,0,0,5"/>
<Border Background="#000000" CornerRadius="4" Padding="10" Margin="0,5">
<Viewbox Height="60">
<TextBlock Text="{Binding CurrentForce, StringFormat={}{0:F4}}" Style="{StaticResource DigitalDisplayStyle}"/>
<TextBlock Text="{Binding DisplayedCurrentForce, StringFormat={}{0:F4}}" Style="{StaticResource DigitalDisplayStyle}"/>
</Viewbox>
</Border>
<TextBlock Text="N" FontSize="12" Foreground="#7F8C8D" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding ForceDisplayUnit}" FontSize="12" Foreground="#7F8C8D" HorizontalAlignment="Center"/>
</StackPanel>
</Border>
@@ -151,13 +151,13 @@
<StackPanel>
<TextBlock Text="{Binding Lang.TestResults}" FontWeight="Bold" FontSize="14" Foreground="#2C3E50" Margin="0,0,0,10"/>
<TextBlock Text="{Binding Lang.PeelStrength}" FontSize="11" Foreground="#7F8C8D"/>
<TextBlock Text="{Binding LatestResult.PeelStrength_N_25mm, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="32" FontWeight="Bold" Foreground="#27AE60" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding PeelStrengthLabel}" FontSize="11" Foreground="#7F8C8D"/>
<TextBlock Text="{Binding DisplayedLatestPeelStrength, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="32" FontWeight="Bold" Foreground="#27AE60" HorizontalAlignment="Center"/>
<Separator Margin="0,10"/>
<TextBlock Text="{Binding Lang.AvgPeelForce}" FontSize="11" Foreground="#7F8C8D"/>
<TextBlock Text="{Binding LatestResult.AvgKineticForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="28" FontWeight="Bold" Foreground="#3498DB" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding AvgPeelForceLabel}" FontSize="11" Foreground="#7F8C8D"/>
<TextBlock Text="{Binding DisplayedLatestAvgKineticForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="28" FontWeight="Bold" Foreground="#3498DB" HorizontalAlignment="Center"/>
</StackPanel>
</Border>