更新UI布局
This commit is contained in:
@@ -90,7 +90,7 @@ namespace COFTester.Models
|
||||
{
|
||||
try
|
||||
{
|
||||
string directory = Path.GetDirectoryName(filePath);
|
||||
string? directory = Path.GetDirectoryName(filePath);
|
||||
if (!string.IsNullOrEmpty(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
@@ -234,6 +234,6 @@ namespace COFTester.Models
|
||||
{
|
||||
void SaveTestResult(TestResult result);
|
||||
List<TestResult> LoadAllTestResults();
|
||||
TestResult LoadTestResult(Guid testId);
|
||||
TestResult? LoadTestResult(Guid testId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,12 @@ namespace COFTester.Resources
|
||||
["AppTitle"] = "CSI-H238M 高精度摩擦系数测试仪",
|
||||
["LanguageButton"] = "中/EN",
|
||||
|
||||
// 导航栏
|
||||
["NavTest"] = "测试",
|
||||
["NavHistory"] = "历史",
|
||||
["NavSettings"] = "设置",
|
||||
["NavCalibration"] = "标定",
|
||||
|
||||
// 左侧面板 - 实时监控
|
||||
["RealTimeMonitor"] = "实时监控",
|
||||
["Force"] = "力值 (N)",
|
||||
@@ -120,6 +126,12 @@ namespace COFTester.Resources
|
||||
["AppTitle"] = "CSI-H238M High-Precision Friction Tester",
|
||||
["LanguageButton"] = "EN/中",
|
||||
|
||||
// Navigation
|
||||
["NavTest"] = "Test",
|
||||
["NavHistory"] = "History",
|
||||
["NavSettings"] = "Settings",
|
||||
["NavCalibration"] = "Calibration",
|
||||
|
||||
// Left Panel - Real-time Monitor
|
||||
["RealTimeMonitor"] = "Real-time Monitor",
|
||||
["Force"] = "Force (N)",
|
||||
@@ -230,6 +242,13 @@ namespace COFTester.Resources
|
||||
// 所有文本属性
|
||||
public string AppTitle => GetString("AppTitle");
|
||||
public string LanguageButton => GetString("LanguageButton");
|
||||
|
||||
// 导航栏
|
||||
public string NavTest => GetString("NavTest");
|
||||
public string NavHistory => GetString("NavHistory");
|
||||
public string NavSettings => GetString("NavSettings");
|
||||
public string NavCalibration => GetString("NavCalibration");
|
||||
|
||||
public string RealTimeMonitor => GetString("RealTimeMonitor");
|
||||
public string Force => GetString("Force");
|
||||
public string Displacement => GetString("Displacement");
|
||||
@@ -326,6 +345,13 @@ namespace COFTester.Resources
|
||||
// 通知所有属性已更改
|
||||
OnPropertyChanged(nameof(AppTitle));
|
||||
OnPropertyChanged(nameof(LanguageButton));
|
||||
|
||||
// 导航栏
|
||||
OnPropertyChanged(nameof(NavTest));
|
||||
OnPropertyChanged(nameof(NavHistory));
|
||||
OnPropertyChanged(nameof(NavSettings));
|
||||
OnPropertyChanged(nameof(NavCalibration));
|
||||
|
||||
OnPropertyChanged(nameof(RealTimeMonitor));
|
||||
OnPropertyChanged(nameof(Force));
|
||||
OnPropertyChanged(nameof(Displacement));
|
||||
|
||||
@@ -120,12 +120,12 @@ namespace COFTester.Services
|
||||
/// <summary>
|
||||
/// 根據 TestId 加載特定測試結果
|
||||
/// </summary>
|
||||
public TestResult LoadTestResult(Guid testId)
|
||||
public TestResult? LoadTestResult(Guid testId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var index = LoadIndex();
|
||||
if (index.TryGetValue(testId, out string fileName))
|
||||
if (index.TryGetValue(testId, out string? fileName) && !string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
string filePath = Path.Combine(_dataDirectory, fileName);
|
||||
if (File.Exists(filePath))
|
||||
@@ -225,7 +225,7 @@ namespace COFTester.Services
|
||||
try
|
||||
{
|
||||
var index = LoadIndex();
|
||||
if (index.TryGetValue(testId, out string fileName))
|
||||
if (index.TryGetValue(testId, out string? fileName) && !string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
string filePath = Path.Combine(_dataDirectory, fileName);
|
||||
if (File.Exists(filePath))
|
||||
|
||||
@@ -35,9 +35,9 @@ namespace COFTester.Services
|
||||
/// <param name="data">原始數據點列表</param>
|
||||
/// <param name="windowSize">濾波窗口大小(建議 3-10)</param>
|
||||
/// <returns>濾波後的數據點列表</returns>
|
||||
public List<TestDataPoint> ApplyMovingAverageFilter(List<TestDataPoint> data, int windowSize)
|
||||
public List<TestDataPoint> ApplyMovingAverageFilter(List<TestDataPoint>? data, int windowSize)
|
||||
{
|
||||
if (data == null || data.Count < windowSize) return data;
|
||||
if (data == null || data.Count < windowSize) return data ?? new List<TestDataPoint>();
|
||||
|
||||
var filteredData = new List<TestDataPoint>();
|
||||
|
||||
@@ -60,9 +60,9 @@ namespace COFTester.Services
|
||||
/// <summary>
|
||||
/// 應用中值濾波器,對於脈衝噪聲有更好的抑制效果
|
||||
/// </summary>
|
||||
public List<TestDataPoint> ApplyMedianFilter(List<TestDataPoint> data, int windowSize)
|
||||
public List<TestDataPoint> ApplyMedianFilter(List<TestDataPoint>? data, int windowSize)
|
||||
{
|
||||
if (data == null || data.Count < windowSize) return data;
|
||||
if (data == null || data.Count < windowSize) return data ?? new List<TestDataPoint>();
|
||||
|
||||
var filteredData = new List<TestDataPoint>();
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace COFTester.Services
|
||||
/// <param name="rawData">原始或濾波後的數據</param>
|
||||
/// <param name="parameters">測試參數(包含標準名稱和計算區間)</param>
|
||||
/// <returns>計算結果</returns>
|
||||
public TestResult CalculateResults(List<TestDataPoint> rawData, TestParameters parameters)
|
||||
public TestResult? CalculateResults(List<TestDataPoint>? rawData, TestParameters parameters)
|
||||
{
|
||||
if (rawData == null || rawData.Count == 0) return null;
|
||||
|
||||
@@ -356,9 +356,9 @@ namespace COFTester.Services
|
||||
/// <summary>
|
||||
/// 檢測數據異常點(基於 3-sigma 原則)
|
||||
/// </summary>
|
||||
public List<TestDataPoint> RemoveOutliers(List<TestDataPoint> data)
|
||||
public List<TestDataPoint> RemoveOutliers(List<TestDataPoint>? data)
|
||||
{
|
||||
if (data == null || data.Count < 10) return data;
|
||||
if (data == null || data.Count < 10) return data ?? new List<TestDataPoint>();
|
||||
|
||||
var forces = data.Select(p => p.Force).ToList();
|
||||
double mean = forces.Average();
|
||||
@@ -383,14 +383,14 @@ namespace COFTester.Services
|
||||
/// </summary>
|
||||
public class SimulatedDataAcquisitionService : IDataAcquisitionService
|
||||
{
|
||||
private CancellationTokenSource _cts;
|
||||
private CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private bool _isAcquiring;
|
||||
private bool _isConnected;
|
||||
private readonly Random _random = new Random();
|
||||
|
||||
public event EventHandler<TestDataPoint> DataReceived;
|
||||
public event EventHandler TestFinished;
|
||||
public event EventHandler<string> ErrorOccurred;
|
||||
public event EventHandler<TestDataPoint>? DataReceived;
|
||||
public event EventHandler? TestFinished;
|
||||
public event EventHandler<string>? ErrorOccurred;
|
||||
|
||||
public bool IsConnected => _isConnected;
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ namespace COFTester.ViewModels
|
||||
private readonly IDataAcquisitionService _daqService;
|
||||
private readonly DataProcessingService _processingService;
|
||||
private readonly DispatcherTimer _clockTimer;
|
||||
private readonly WpfPlot _wpfPlot;
|
||||
private WpfPlot? _wpfPlot;
|
||||
private readonly AppConfig _config;
|
||||
private ScottPlot.Plottables.Scatter _scatterPlot = null!;
|
||||
private ScottPlot.Plottables.Scatter? _scatterPlot;
|
||||
private readonly Dictionary<Guid, ScottPlot.Plottables.Scatter> _testCurves = new();
|
||||
|
||||
private double _currentForce;
|
||||
@@ -38,11 +38,10 @@ namespace COFTester.ViewModels
|
||||
private int _testCounter = 0;
|
||||
private bool _disposed = false;
|
||||
|
||||
public MainViewModel(IDataAcquisitionService daqService, DataProcessingService processingService, WpfPlot wpfPlot, AppConfig config)
|
||||
public MainViewModel(IDataAcquisitionService daqService, DataProcessingService processingService, AppConfig config)
|
||||
{
|
||||
_daqService = daqService ?? throw new ArgumentNullException(nameof(daqService));
|
||||
_processingService = processingService ?? throw new ArgumentNullException(nameof(processingService));
|
||||
_wpfPlot = wpfPlot ?? throw new ArgumentNullException(nameof(wpfPlot));
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
_realTimePoints = new List<TestDataPoint>();
|
||||
|
||||
@@ -63,8 +62,8 @@ namespace COFTester.ViewModels
|
||||
ResetCommand = new RelayCommand(Reset, () => !_isTesting && IsConnected);
|
||||
SwitchLanguageCommand = new RelayCommand(SwitchLanguage);
|
||||
OpenConfigCommand = new RelayCommand(OpenConfig);
|
||||
ClearAllTestsCommand = new RelayCommand(ClearAllTests, () => !_isTesting && TestRecords.Count > 0);
|
||||
GenerateReportCommand = new RelayCommand(GenerateReport, () => TestRecords.Count > 0);
|
||||
ClearAllTestsCommand = new RelayCommand(ClearAllTests, () => !_isTesting && TestRecords?.Count > 0);
|
||||
GenerateReportCommand = new RelayCommand(GenerateReport, () => TestRecords?.Count > 0);
|
||||
|
||||
Parameters = _config.DefaultTestParameters ?? new TestParameters();
|
||||
TestRecords = new ObservableCollection<TestResult>();
|
||||
@@ -74,9 +73,6 @@ namespace COFTester.ViewModels
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
};
|
||||
|
||||
// 初始化 ScottPlot
|
||||
InitializeScottPlot();
|
||||
|
||||
// 启动时钟更新
|
||||
_clockTimer = new DispatcherTimer
|
||||
{
|
||||
@@ -89,6 +85,15 @@ namespace COFTester.ViewModels
|
||||
AutoConnectOnStartup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置图表控件(由TestPage调用)
|
||||
/// </summary>
|
||||
public void SetPlot(WpfPlot wpfPlot)
|
||||
{
|
||||
_wpfPlot = wpfPlot ?? throw new ArgumentNullException(nameof(wpfPlot));
|
||||
InitializeScottPlot();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 啟動時根據配置自動連接
|
||||
/// </summary>
|
||||
@@ -124,6 +129,8 @@ namespace COFTester.ViewModels
|
||||
/// </summary>
|
||||
private void InitializeScottPlot()
|
||||
{
|
||||
if (_wpfPlot == null) return;
|
||||
|
||||
_wpfPlot.Plot.Clear();
|
||||
|
||||
// 设置支持中文的字体(必须在添加任何元素之前)
|
||||
@@ -203,6 +210,8 @@ namespace COFTester.ViewModels
|
||||
/// </summary>
|
||||
private void UpdateScottPlot()
|
||||
{
|
||||
if (_wpfPlot == null || _scatterPlot == null) return;
|
||||
|
||||
// 移除旧的散点图
|
||||
_wpfPlot.Plot.Remove(_scatterPlot);
|
||||
|
||||
@@ -424,6 +433,8 @@ namespace COFTester.ViewModels
|
||||
var filteredData = _processingService.ApplyMovingAverageFilter(rawDataList, 5);
|
||||
var result = _processingService.CalculateResults(filteredData, Parameters);
|
||||
|
||||
if (result == null) return;
|
||||
|
||||
// 保存原始数据用于再分析
|
||||
result.RawData = rawDataList;
|
||||
result.SampleNumber = $"#{++_testCounter}";
|
||||
@@ -431,7 +442,7 @@ namespace COFTester.ViewModels
|
||||
// 监听IsVisible属性变化
|
||||
result.PropertyChanged += (s, args) =>
|
||||
{
|
||||
if (args.PropertyName == nameof(TestResult.IsVisible))
|
||||
if (args?.PropertyName == nameof(TestResult.IsVisible))
|
||||
{
|
||||
UpdateAllCurvesVisibility();
|
||||
}
|
||||
@@ -596,7 +607,7 @@ namespace COFTester.ViewModels
|
||||
/// </summary>
|
||||
private void AddCurveToPlot(TestResult result)
|
||||
{
|
||||
if (result.RawData == null || result.RawData.Count == 0)
|
||||
if (_wpfPlot == null || result.RawData == null || result.RawData.Count == 0)
|
||||
return;
|
||||
|
||||
var xData = result.RawData.Select(p => p.Displacement).ToArray();
|
||||
@@ -627,6 +638,8 @@ namespace COFTester.ViewModels
|
||||
/// </summary>
|
||||
private void UpdateAllCurvesVisibility()
|
||||
{
|
||||
if (_wpfPlot == null) return;
|
||||
|
||||
foreach (var record in TestRecords)
|
||||
{
|
||||
if (_testCurves.TryGetValue(record.TestId, out var curve))
|
||||
@@ -644,8 +657,11 @@ namespace COFTester.ViewModels
|
||||
{
|
||||
TestRecords.Clear();
|
||||
_testCurves.Clear();
|
||||
_wpfPlot.Plot.Clear();
|
||||
InitializeScottPlot();
|
||||
if (_wpfPlot != null)
|
||||
{
|
||||
_wpfPlot.Plot.Clear();
|
||||
InitializeScottPlot();
|
||||
}
|
||||
_testCounter = 0;
|
||||
StatusMessage = "已清除所有测试记录";
|
||||
}
|
||||
@@ -732,9 +748,12 @@ namespace COFTester.ViewModels
|
||||
SetChineseFont();
|
||||
|
||||
// 更新图表坐标轴标签
|
||||
_wpfPlot.Plot.XLabel(Lang.DisplacementAxis);
|
||||
_wpfPlot.Plot.YLabel(Lang.ForceAxis);
|
||||
_wpfPlot.Refresh();
|
||||
if (_wpfPlot != null)
|
||||
{
|
||||
_wpfPlot.Plot.XLabel(Lang.DisplacementAxis);
|
||||
_wpfPlot.Plot.YLabel(Lang.ForceAxis);
|
||||
_wpfPlot.Refresh();
|
||||
}
|
||||
|
||||
// 更新当前状态消息
|
||||
if (_statusMessage == "系统就绪" || _statusMessage == "System Ready")
|
||||
|
||||
76
CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml
Normal file
76
CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml
Normal file
@@ -0,0 +1,76 @@
|
||||
<UserControl x:Class="COFTester.Views.CalibrationPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Background="Transparent">
|
||||
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="CardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="15"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="2" Opacity="0.1"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<SolidColorBrush x:Key="GrayBrush" Color="#7F8C8D"/>
|
||||
<SolidColorBrush x:Key="AccentBrush" Color="#3498DB"/>
|
||||
<SolidColorBrush x:Key="SuccessBrush" Color="#27AE60"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="传感器标定" FontWeight="Bold" Margin="0,0,0,20" Foreground="{StaticResource GrayBrush}" FontSize="18"/>
|
||||
|
||||
<!-- 连接状态 -->
|
||||
<Border Background="#F8F9FA" CornerRadius="4" Padding="15" Margin="0,0,0,20">
|
||||
<StackPanel>
|
||||
<TextBlock Text="设备连接" FontWeight="Bold" Margin="0,0,0,10" FontSize="14"/>
|
||||
<TextBlock Text="{Binding ConnectionInfo}" FontSize="12" Foreground="{StaticResource GrayBrush}" Margin="0,0,0,10"/>
|
||||
|
||||
<Button Command="{Binding ToggleConnectionCommand}" Height="50" Foreground="White" FontSize="14">
|
||||
<Button.Content>
|
||||
<TextBlock Text="{Binding ConnectionButtonText}"/>
|
||||
</Button.Content>
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#27AE60"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
||||
<Setter Property="Background" Value="#E74C3C"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 标定操作 -->
|
||||
<Border Background="#F8F9FA" CornerRadius="4" Padding="15">
|
||||
<StackPanel>
|
||||
<TextBlock Text="标定操作" FontWeight="Bold" Margin="0,0,0,10" FontSize="14"/>
|
||||
<TextBlock Text="请确保设备已连接,然后执行以下标定步骤:" TextWrapping="Wrap" Margin="0,0,0,15" FontSize="12"/>
|
||||
|
||||
<Button Content="零点标定" Command="{Binding ResetCommand}" Height="50" Foreground="White" FontSize="14" Margin="0,0,0,10">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource AccentBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
<TextBlock Text="说明:在无负载状态下执行零点标定,将当前读数设为零点。"
|
||||
TextWrapping="Wrap" FontSize="11" Foreground="{StaticResource GrayBrush}" Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
12
CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml.cs
Normal file
12
CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace COFTester.Views
|
||||
{
|
||||
public partial class CalibrationPage : UserControl
|
||||
{
|
||||
public CalibrationPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
95
CSI-H238M/CSI-H238M/Views/HistoryPage.xaml
Normal file
95
CSI-H238M/CSI-H238M/Views/HistoryPage.xaml
Normal file
@@ -0,0 +1,95 @@
|
||||
<UserControl x:Class="COFTester.Views.HistoryPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Background="Transparent">
|
||||
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="CardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="15"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="2" Opacity="0.1"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<SolidColorBrush x:Key="GrayBrush" Color="#7F8C8D"/>
|
||||
<SolidColorBrush x:Key="AccentBrush" Color="#3498DB"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="320"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 左侧:数据列表 -->
|
||||
<Border Grid.Column="0" Style="{StaticResource CardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Text="{Binding Lang.TestList}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}" FontSize="16"/>
|
||||
|
||||
<DataGrid Grid.Row="1" ItemsSource="{Binding TestRecords}" AutoGenerateColumns="False"
|
||||
IsReadOnly="True" CanUserAddRows="False" CanUserDeleteRows="False"
|
||||
GridLinesVisibility="Horizontal" HeadersVisibility="Column"
|
||||
Background="White" BorderThickness="0">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="样本编号" Binding="{Binding SampleNumber}" Width="100"/>
|
||||
<DataGridTextColumn Header="测试时间" Binding="{Binding TestDateTime, StringFormat={}{0:yyyy-MM-dd HH:mm:ss}}" Width="150"/>
|
||||
<DataGridTextColumn Header="静摩擦系数" Binding="{Binding StaticCOF, StringFormat={}{0:F4}}" Width="120"/>
|
||||
<DataGridTextColumn Header="动摩擦系数" Binding="{Binding KineticCOF, StringFormat={}{0:F4}}" Width="120"/>
|
||||
<DataGridTextColumn Header="最大力值(N)" Binding="{Binding MaxForce, StringFormat={}{0:F3}}" Width="120"/>
|
||||
<DataGridTextColumn Header="平均力值(N)" Binding="{Binding AvgKineticForce, StringFormat={}{0:F3}}" Width="120"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 右侧:统计和操作 -->
|
||||
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<!-- 成组统计 -->
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.GroupStatistics}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
<TextBlock Text="{Binding GroupStatistics}" TextWrapping="Wrap" FontSize="12"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<Button Content="{Binding Lang.GenerateReport}" Command="{Binding GenerateReportCommand}"
|
||||
Height="50" Foreground="White" FontSize="14" Margin="0,0,0,10">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource AccentBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
<Button Content="{Binding Lang.ClearAllTests}" Command="{Binding ClearAllTestsCommand}"
|
||||
Height="50" Foreground="White" FontSize="14">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource GrayBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
12
CSI-H238M/CSI-H238M/Views/HistoryPage.xaml.cs
Normal file
12
CSI-H238M/CSI-H238M/Views/HistoryPage.xaml.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace COFTester.Views
|
||||
{
|
||||
public partial class HistoryPage : UserControl
|
||||
{
|
||||
public HistoryPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,475 +1,128 @@
|
||||
<Window x:Class="COFTester.Views.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:scottplot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
||||
mc:Ignorable="d"
|
||||
Title="CSI-H238M Precision Friction Tester" Height="800" Width="1200"
|
||||
Title="CSI-H238M Precision Friction Tester" Height="800" Width="1024"
|
||||
Background="#F0F3F5">
|
||||
|
||||
<Window.Resources>
|
||||
<!-- 畫刷定義 -->
|
||||
<SolidColorBrush x:Key="PrimaryBrush" Color="#2C3E50"/>
|
||||
<SolidColorBrush x:Key="AccentBrush" Color="#3498DB"/>
|
||||
<SolidColorBrush x:Key="SuccessBrush" Color="#27AE60"/>
|
||||
<SolidColorBrush x:Key="DangerBrush" Color="#E74C3C"/>
|
||||
<SolidColorBrush x:Key="WarningBrush" Color="#F39C12"/>
|
||||
<SolidColorBrush x:Key="GrayBrush" Color="#7F8C8D"/>
|
||||
<SolidColorBrush x:Key="LightGrayBrush" Color="#BDC3C7"/>
|
||||
|
||||
<!-- 卡片樣式 -->
|
||||
<Style x:Key="CardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="15"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Effect">
|
||||
<Style x:Key="NavButtonStyle" TargetType="RadioButton">
|
||||
<Setter Property="Width" Value="100"/>
|
||||
<Setter Property="Height" Value="100"/>
|
||||
<Setter Property="Margin" Value="0,5"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="#7F8C8D"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="2" Opacity="0.1"/>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
<Border Background="{TemplateBinding Background}">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock Text="{TemplateBinding Tag}" FontFamily="Segoe MDL2 Assets" FontSize="32" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center" Margin="0,0,0,5"/>
|
||||
<TextBlock Text="{TemplateBinding Content}" FontSize="12" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter Property="Background" Value="#3498DB"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#ECF0F1"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 數字顯示樣式 -->
|
||||
<Style x:Key="DigitalDisplay" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="42"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PrimaryBrush}"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Header -->
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- Main Content -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Status Bar -->
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 1. Header -->
|
||||
<Border Grid.Row="0" Style="{StaticResource CardStyle}" Margin="5,5,5,10">
|
||||
<Border.Background>
|
||||
<SolidColorBrush Color="#2C3E50"/>
|
||||
</Border.Background>
|
||||
<DockPanel>
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Left">
|
||||
<Ellipse Width="15" Height="15" Margin="0,0,10,0">
|
||||
<Ellipse.Fill>
|
||||
<SolidColorBrush Color="#27AE60"/>
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
<TextBlock Text="{Binding Lang.AppTitle}" Foreground="White" FontSize="18" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Right" HorizontalAlignment="Right">
|
||||
<Button Content="{Binding Lang.LanguageButton}" Command="{Binding SwitchLanguageCommand}"
|
||||
Width="60" Height="30" Margin="0,0,10,0"
|
||||
Background="#34495E" Foreground="White" BorderThickness="0"
|
||||
Cursor="Hand" FontSize="12" ToolTip="{Binding Lang.LanguageTooltip}"/>
|
||||
<TextBlock Text="{Binding CurrentDateTime, StringFormat={}{0:yyyy-MM-dd HH:mm:ss}}" VerticalAlignment="Center">
|
||||
<TextBlock.Foreground>
|
||||
<SolidColorBrush Color="#BDC3C7"/>
|
||||
</TextBlock.Foreground>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
<Border Grid.Column="0" Background="#2C3E50">
|
||||
<StackPanel>
|
||||
<Border Height="60" Background="#34495E">
|
||||
<Ellipse Width="40" Height="40" Fill="#27AE60"/>
|
||||
</Border>
|
||||
<RadioButton x:Name="NavTest" Content="{Binding Lang.NavTest}" Tag="" Style="{StaticResource NavButtonStyle}" IsChecked="True" Checked="NavButton_Checked"/>
|
||||
<RadioButton x:Name="NavHistory" Content="{Binding Lang.NavHistory}" Tag="" Style="{StaticResource NavButtonStyle}" Checked="NavButton_Checked"/>
|
||||
<RadioButton x:Name="NavSettings" Content="{Binding Lang.NavSettings}" Tag="" Style="{StaticResource NavButtonStyle}" Checked="NavButton_Checked"/>
|
||||
<RadioButton x:Name="NavCalibration" Content="{Binding Lang.NavCalibration}" Tag="" Style="{StaticResource NavButtonStyle}" Checked="NavButton_Checked"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 2. Main Content -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="130"/>
|
||||
<!-- Left: Test List -->
|
||||
<ColumnDefinition Width="300"/>
|
||||
<!-- Left-Center: Controls & Params -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- Center: Chart -->
|
||||
<ColumnDefinition Width="300"/>
|
||||
<!-- Right: Results -->
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 2.0 Test List Panel -->
|
||||
<Border Grid.Column="0" Style="{StaticResource CardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Text="{Binding Lang.TestList}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
|
||||
<ListBox Grid.Row="1" ItemsSource="{Binding TestRecords}" SelectedItem="{Binding LatestResult}"
|
||||
Background="Transparent" BorderThickness="0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,5">
|
||||
<CheckBox IsChecked="{Binding IsVisible}" VerticalAlignment="Center" Margin="0,0,5,0"/>
|
||||
<TextBlock Text="{Binding SampleNumber}" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<Button Grid.Row="2" Content="{Binding Lang.ClearAllTests}" Command="{Binding ClearAllTestsCommand}"
|
||||
Height="32" Foreground="White" FontSize="12" Margin="0,10,0,0">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource GrayBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Border Grid.Row="0" Background="#2C3E50" Padding="15,0">
|
||||
<DockPanel>
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Left" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding Lang.AppTitle}" Foreground="White" FontSize="16" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Right" HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||
<Button Content="{Binding Lang.LanguageButton}" Command="{Binding SwitchLanguageCommand}" Width="60" Height="30" Margin="0,0,15,0" Background="#34495E" Foreground="White" BorderThickness="0" Cursor="Hand" FontSize="12"/>
|
||||
<TextBlock Text="{Binding CurrentDateTime, StringFormat={}{0:yyyy-MM-dd HH:mm:ss}}" Foreground="#BDC3C7" VerticalAlignment="Center" FontSize="12"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 2.1 Left Panel: Controls & Parameters -->
|
||||
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.RealTimeMonitor}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
<TextBlock Text="{Binding Lang.Force}" FontSize="12" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding CurrentForce, StringFormat={}{0:F4}}" Style="{StaticResource DigitalDisplay}" Foreground="{StaticResource DangerBrush}"/>
|
||||
<Separator Margin="0,10"/>
|
||||
<TextBlock Text="{Binding Lang.Displacement}" FontSize="12" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding CurrentDisp, StringFormat={}{0:F2}}" Style="{StaticResource DigitalDisplay}" FontSize="32"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<ContentControl Grid.Row="1" x:Name="ContentArea" Margin="10"/>
|
||||
|
||||
<Border Style="{StaticResource CardStyle}" Margin="5,10,5,5">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.TestControl}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
|
||||
<!-- 連接控制 - 單一切換按鈕 -->
|
||||
<Button Command="{Binding ToggleConnectionCommand}" Height="36" Foreground="White" FontSize="12" Margin="0,0,0,10">
|
||||
<Button.Content>
|
||||
<TextBlock Text="{Binding ConnectionButtonText}"/>
|
||||
</Button.Content>
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#27AE60"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
||||
<Setter Property="Background" Value="#E74C3C"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding IsConnecting}" Value="True">
|
||||
<Setter Property="Background" Value="#F39C12"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
<!-- 連接狀態顯示 -->
|
||||
<Border Background="#F8F9FA" CornerRadius="4" Padding="8" Margin="0,0,0,10">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding ConnectionInfo}" FontSize="11" Foreground="{StaticResource GrayBrush}" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Button Content="{Binding Lang.StartTest}" Command="{Binding StartCommand}" Height="50" Foreground="White" FontWeight="Bold" Margin="0,5" FontSize="16">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource SuccessBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
<Button Content="{Binding Lang.Stop}" Command="{Binding StopCommand}" Height="40" Foreground="White" Margin="0,5" FontSize="14">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource DangerBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
<Button Content="{Binding Lang.ResetSystem}" Command="{Binding ResetCommand}" Height="40" Foreground="White" Margin="0,5" FontSize="14">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource AccentBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource CardStyle}" Margin="5,10,5,5">
|
||||
<StackPanel>
|
||||
<Grid Margin="0,0,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding Lang.TestParameters}" FontWeight="Bold" Foreground="{StaticResource GrayBrush}" VerticalAlignment="Center"/>
|
||||
<Button Grid.Column="1" Command="{Binding OpenConfigCommand}"
|
||||
Width="32" Height="32"
|
||||
Background="{StaticResource AccentBrush}"
|
||||
BorderThickness="0"
|
||||
Cursor="Hand"
|
||||
ToolTip="{Binding Lang.DetailedConfig}"
|
||||
Padding="0">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="16" Foreground="White"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
<TextBlock Text="{Binding Lang.Standard}" Margin="0,5,0,2"/>
|
||||
<ComboBox SelectedValue="{Binding Parameters.Standard, Mode=TwoWay}"
|
||||
SelectedValuePath="Content" Margin="0,0,0,8" Height="36"
|
||||
VerticalContentAlignment="Center">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style TargetType="ComboBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="10,8"/>
|
||||
<Setter Property="MinHeight" Value="36"/>
|
||||
</Style>
|
||||
</ComboBox.ItemContainerStyle>
|
||||
<ComboBoxItem Content="GB 10006"/>
|
||||
<ComboBoxItem Content="ISO 8295"/>
|
||||
<ComboBoxItem Content="ASTM D1894"/>
|
||||
<ComboBoxItem Content="GB/T 22895"/>
|
||||
<ComboBoxItem Content="TAPPI T816"/>
|
||||
<ComboBoxItem Content="GB/T 2792"/>
|
||||
<ComboBoxItem Content="GB/T 17200"/>
|
||||
<ComboBoxItem Content="Custom"/>
|
||||
</ComboBox>
|
||||
|
||||
<!-- 滑块质量/试样宽度 - 根据标准动态切换 -->
|
||||
<TextBlock x:Name="MassOrWidthLabel" Margin="0,5,0,2">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{Binding Lang.SledMass}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Parameters.Standard}" Value="GB/T 2792">
|
||||
<Setter Property="Text" Value="{Binding Lang.SampleWidth}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
<TextBox x:Name="MassOrWidthValue" Margin="0,0,0,8" IsReadOnly="True" Background="#F5F5F5">
|
||||
<TextBox.Style>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Text" Value="{Binding Parameters.SledMass}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Parameters.Standard}" Value="GB/T 2792">
|
||||
<Setter Property="Text" Value="{Binding Parameters.SampleWidth}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBox.Style>
|
||||
</TextBox>
|
||||
|
||||
<TextBlock Text="{Binding Lang.TestSpeed}" Margin="0,5,0,2"/>
|
||||
<TextBox Text="{Binding Parameters.TestSpeed}" Margin="0,0,0,8" IsReadOnly="True" Background="#F5F5F5"/>
|
||||
<TextBlock Text="{Binding Lang.TestDuration}" Margin="0,5,0,2"/>
|
||||
<TextBox Text="{Binding Parameters.TestDuration}" Margin="0,0,0,8" IsReadOnly="True" Background="#F5F5F5"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- 2.2 Center Panel: Real-time Chart -->
|
||||
<Border Grid.Column="2" Style="{StaticResource CardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{Binding Lang.FrictionCurve}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}" FontSize="14"/>
|
||||
|
||||
<!-- 显示全部曲线勾选框 -->
|
||||
<CheckBox Grid.Row="1" Content="{Binding Lang.ShowAllCurves}" IsChecked="{Binding ShowAllCurves}"
|
||||
Margin="0,0,0,10" FontSize="12"/>
|
||||
|
||||
<!-- ScottPlot 实时曲线 -->
|
||||
<scottplot:WpfPlot Grid.Row="2" x:Name="FrictionPlot" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 2.3 Right Panel: Results -->
|
||||
<ScrollViewer Grid.Column="3" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.TestResults}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
|
||||
<!-- 摩擦系数模式 - 默认显示 -->
|
||||
<StackPanel x:Name="FrictionResultsPanel">
|
||||
<StackPanel.Style>
|
||||
<Style TargetType="StackPanel">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Parameters.Standard}" Value="GB/T 2792">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Style>
|
||||
|
||||
<TextBlock Text="{Binding Lang.StaticCOF}" FontSize="12"/>
|
||||
<TextBlock Text="{Binding LatestResult.StaticCOF, StringFormat={}{0:F4}, FallbackValue=--}" FontSize="28" FontWeight="Bold" Foreground="{StaticResource WarningBrush}"/>
|
||||
|
||||
<Separator Margin="0,10"/>
|
||||
|
||||
<TextBlock Text="{Binding Lang.KineticCOF}" FontSize="12"/>
|
||||
<TextBlock Text="{Binding LatestResult.KineticCOF, StringFormat={}{0:F4}, FallbackValue=--}" FontSize="28" FontWeight="Bold" Foreground="{StaticResource WarningBrush}"/>
|
||||
|
||||
<Separator Margin="0,10"/>
|
||||
|
||||
<TextBlock Text="{Binding Lang.MaxForce}" FontSize="12"/>
|
||||
<TextBlock Text="{Binding LatestResult.MaxForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="20" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 剥离强度模式 - GB/T 2792 时显示 -->
|
||||
<StackPanel x:Name="PeelResultsPanel">
|
||||
<StackPanel.Style>
|
||||
<Style TargetType="StackPanel">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Parameters.Standard}" Value="GB/T 2792">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Style>
|
||||
|
||||
<TextBlock Text="{Binding Lang.PeelStrength}" FontSize="12"/>
|
||||
<TextBlock Text="{Binding LatestResult.PeelStrength_N_25mm, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="28" FontWeight="Bold" Foreground="{StaticResource SuccessBrush}"/>
|
||||
|
||||
<Separator Margin="0,10"/>
|
||||
|
||||
<TextBlock Text="{Binding Lang.AvgPeelForce}" FontSize="12"/>
|
||||
<TextBlock Text="{Binding LatestResult.AvgKineticForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="28" FontWeight="Bold" Foreground="{StaticResource AccentBrush}"/>
|
||||
|
||||
<Separator Margin="0,10"/>
|
||||
|
||||
<TextBlock Text="{Binding Lang.MaxForce}" FontSize="12"/>
|
||||
<TextBlock Text="{Binding LatestResult.MaxForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="20" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource CardStyle}" Margin="5,10,5,5">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.Statistics}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
|
||||
<!-- 标签页控件 -->
|
||||
<TabControl Background="Transparent" BorderThickness="0">
|
||||
<!-- 当前测试统计 -->
|
||||
<TabItem Header="{Binding Lang.CurrentTest}">
|
||||
<Grid Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Lang.AvgForce}" Margin="0,5"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding LatestResult.AvgKineticForce, StringFormat={}{0:F3} N, FallbackValue=--}" FontWeight="Bold" Margin="5,5" HorizontalAlignment="Right"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding Lang.TestTime}" Margin="0,5"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LatestResult.TestDateTime, StringFormat={}{0:HH:mm:ss}, FallbackValue=--}" FontWeight="Bold" Margin="5,5" HorizontalAlignment="Right"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding Lang.DataPoints}" Margin="0,5"/>
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding DataPointsCount, FallbackValue=0}" FontWeight="Bold" Margin="5,5" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<!-- 成组统计 -->
|
||||
<TabItem Header="{Binding Lang.GroupStatistics}">
|
||||
<TextBlock Text="{Binding GroupStatistics}" Margin="0,10,0,0" TextWrapping="Wrap" FontSize="12"/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
<Button Content="{Binding Lang.GenerateReport}" Command="{Binding GenerateReportCommand}"
|
||||
Margin="0,15,0,0" Height="40" Foreground="White" FontSize="14">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#95A5A6"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<StatusBar Grid.Row="2" Background="White" Padding="10,5">
|
||||
<StatusBarItem>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Lang.Status}" Foreground="#7F8C8D" Margin="0,0,5,0"/>
|
||||
<TextBlock Text="{Binding StatusMessage}" Foreground="#2C3E50" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator/>
|
||||
<StatusBarItem>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Ellipse Width="8" Height="8" Margin="0,0,5,0">
|
||||
<Ellipse.Style>
|
||||
<Style TargetType="Ellipse">
|
||||
<Setter Property="Fill" Value="#E74C3C"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
||||
<Setter Property="Fill" Value="#27AE60"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Ellipse.Style>
|
||||
</Ellipse>
|
||||
<TextBlock>
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{Binding Lang.NotConnected}"/>
|
||||
<Setter Property="Foreground" Value="#E74C3C"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
||||
<Setter Property="Text" Value="{Binding Lang.Connected}"/>
|
||||
<Setter Property="Foreground" Value="#27AE60"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding IsConnecting}" Value="True">
|
||||
<Setter Property="Text" Value="{Binding Lang.Connecting}"/>
|
||||
<Setter Property="Foreground" Value="#F39C12"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator/>
|
||||
<StatusBarItem>
|
||||
<TextBlock Text="{Binding CommunicationMode}" Foreground="#7F8C8D" FontSize="11"/>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
|
||||
<!-- 3. Status Bar -->
|
||||
<StatusBar Grid.Row="2" Background="Transparent" Margin="5">
|
||||
<StatusBarItem>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Lang.Status}" Foreground="{StaticResource GrayBrush}"/>
|
||||
<TextBlock Text="{Binding StatusMessage}" Foreground="{StaticResource PrimaryBrush}" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator/>
|
||||
<StatusBarItem>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Ellipse Width="8" Height="8" Margin="0,0,5,0">
|
||||
<Ellipse.Style>
|
||||
<Style TargetType="Ellipse">
|
||||
<Setter Property="Fill" Value="#E74C3C"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
||||
<Setter Property="Fill" Value="#27AE60"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Ellipse.Style>
|
||||
</Ellipse>
|
||||
<TextBlock>
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{Binding Lang.NotConnected}"/>
|
||||
<Setter Property="Foreground" Value="#E74C3C"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
||||
<Setter Property="Text" Value="{Binding Lang.Connected}"/>
|
||||
<Setter Property="Foreground" Value="#27AE60"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding IsConnecting}" Value="True">
|
||||
<Setter Property="Text" Value="{Binding Lang.Connecting}"/>
|
||||
<Setter Property="Foreground" Value="#F39C12"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator/>
|
||||
<StatusBarItem>
|
||||
<TextBlock Text="{Binding CommunicationMode}" Foreground="{StaticResource GrayBrush}" FontSize="11"/>
|
||||
</StatusBarItem>
|
||||
<Separator/>
|
||||
<StatusBarItem>
|
||||
<TextBlock Foreground="{StaticResource GrayBrush}">
|
||||
<Run Text="{Binding Lang.DataPointsCount, Mode=OneWay}"/>
|
||||
<Run Text="{Binding DataPointsCount, Mode=OneWay}"/>
|
||||
</TextBlock>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
|
||||
@@ -2,37 +2,85 @@
|
||||
using COFTester.Services;
|
||||
using COFTester.Models;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace COFTester.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// MainWindow.xaml 的交互邏輯
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private readonly MainViewModel _viewModel;
|
||||
private readonly TestPage _testPage;
|
||||
private readonly HistoryPage _historyPage;
|
||||
private readonly SettingsPage _settingsPage;
|
||||
private readonly CalibrationPage _calibrationPage;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 加載配置
|
||||
// 加载配置
|
||||
var config = AppConfig.Load(AppConfig.GetDefaultConfigPath());
|
||||
|
||||
// 根據配置創建數據採集服務(支持 Modbus TCP/RTU/ASCII 和模擬模式)
|
||||
// 创建数据采集服务
|
||||
IDataAcquisitionService daqService = ModbusServiceFactory.CreateService(config);
|
||||
var processingService = new DataProcessingService();
|
||||
|
||||
// 設置 DataContext
|
||||
_viewModel = new MainViewModel(daqService, processingService, FrictionPlot, config);
|
||||
// 创建ViewModel
|
||||
_viewModel = new MainViewModel(daqService, processingService, config);
|
||||
this.DataContext = _viewModel;
|
||||
|
||||
// 创建所有页面
|
||||
_testPage = new TestPage();
|
||||
_historyPage = new HistoryPage();
|
||||
_settingsPage = new SettingsPage();
|
||||
_calibrationPage = new CalibrationPage();
|
||||
|
||||
// 设置页面的DataContext
|
||||
_testPage.SetViewModel(_viewModel);
|
||||
_historyPage.DataContext = _viewModel;
|
||||
_settingsPage.DataContext = _viewModel;
|
||||
_calibrationPage.DataContext = _viewModel;
|
||||
|
||||
// 默认显示测试页面(确保在 Loaded 事件后设置)
|
||||
this.Loaded += (s, e) =>
|
||||
{
|
||||
if (ContentArea != null)
|
||||
{
|
||||
ContentArea.Content = _testPage;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void NavButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 确保 ContentArea 已初始化
|
||||
if (ContentArea == null) return;
|
||||
|
||||
if (sender is RadioButton radioButton)
|
||||
{
|
||||
if (radioButton == NavTest)
|
||||
{
|
||||
ContentArea.Content = _testPage;
|
||||
}
|
||||
else if (radioButton == NavHistory)
|
||||
{
|
||||
ContentArea.Content = _historyPage;
|
||||
}
|
||||
else if (radioButton == NavSettings)
|
||||
{
|
||||
ContentArea.Content = _settingsPage;
|
||||
}
|
||||
else if (radioButton == NavCalibration)
|
||||
{
|
||||
ContentArea.Content = _calibrationPage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed(System.EventArgs e)
|
||||
{
|
||||
// 清理資源
|
||||
_viewModel?.Dispose();
|
||||
base.OnClosed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
75
CSI-H238M/CSI-H238M/Views/SettingsPage.xaml
Normal file
75
CSI-H238M/CSI-H238M/Views/SettingsPage.xaml
Normal file
@@ -0,0 +1,75 @@
|
||||
<UserControl x:Class="COFTester.Views.SettingsPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Background="Transparent">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="CardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="15"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="2" Opacity="0.1"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<SolidColorBrush x:Key="GrayBrush" Color="#7F8C8D"/>
|
||||
<SolidColorBrush x:Key="AccentBrush" Color="#3498DB"/>
|
||||
</UserControl.Resources>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel MaxWidth="800">
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<Grid Margin="0,0,0,15">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding Lang.TestParameters}" FontWeight="Bold" Foreground="{StaticResource GrayBrush}" VerticalAlignment="Center" FontSize="16"/>
|
||||
<Button Grid.Column="1" Command="{Binding OpenConfigCommand}" Width="120" Height="40" Background="{StaticResource AccentBrush}" BorderThickness="0" Cursor="Hand" Foreground="White" FontSize="14">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="16" Margin="0,0,5,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Lang.DetailedConfig}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Grid>
|
||||
<TextBlock Text="{Binding Lang.Standard}" Margin="0,10,0,5" FontSize="13"/>
|
||||
<ComboBox SelectedValue="{Binding Parameters.Standard, Mode=TwoWay}" SelectedValuePath="Content" Margin="0,0,0,15" Height="40" VerticalContentAlignment="Center" FontSize="13">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style TargetType="ComboBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="10,8"/>
|
||||
<Setter Property="MinHeight" Value="40"/>
|
||||
</Style>
|
||||
</ComboBox.ItemContainerStyle>
|
||||
<ComboBoxItem Content="GB 10006"/>
|
||||
<ComboBoxItem Content="ISO 8295"/>
|
||||
<ComboBoxItem Content="ASTM D1894"/>
|
||||
<ComboBoxItem Content="GB/T 22895"/>
|
||||
<ComboBoxItem Content="TAPPI T816"/>
|
||||
<ComboBoxItem Content="GB/T 2792"/>
|
||||
<ComboBoxItem Content="GB/T 17200"/>
|
||||
<ComboBoxItem Content="Custom"/>
|
||||
</ComboBox>
|
||||
<TextBlock Text="{Binding Lang.TestSpeed}" Margin="0,10,0,5" FontSize="13"/>
|
||||
<TextBox Text="{Binding Parameters.TestSpeed, Mode=OneWay}" Margin="0,0,0,15" IsReadOnly="True" Background="#F5F5F5" Height="40" VerticalContentAlignment="Center" FontSize="13"/>
|
||||
<TextBlock Text="{Binding Lang.TestDuration}" Margin="0,10,0,5" FontSize="13"/>
|
||||
<TextBox Text="{Binding Parameters.TestDuration, Mode=OneWay}" Margin="0,0,0,15" IsReadOnly="True" Background="#F5F5F5" Height="40" VerticalContentAlignment="Center" FontSize="13"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="系统设置" FontWeight="Bold" Margin="0,0,0,15" Foreground="{StaticResource GrayBrush}" FontSize="16"/>
|
||||
<TextBlock Text="通信模式" Margin="0,10,0,5" FontSize="13"/>
|
||||
<TextBox Text="{Binding CommunicationMode, Mode=OneWay}" IsReadOnly="True" Background="#F5F5F5" Height="40" VerticalContentAlignment="Center" FontSize="13" Margin="0,0,0,15"/>
|
||||
<TextBlock Text="连接信息" Margin="0,10,0,5" FontSize="13"/>
|
||||
<TextBox Text="{Binding ConnectionInfo, Mode=OneWay}" IsReadOnly="True" Background="#F5F5F5" Height="40" VerticalContentAlignment="Center" FontSize="13"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
|
||||
|
||||
12
CSI-H238M/CSI-H238M/Views/SettingsPage.xaml.cs
Normal file
12
CSI-H238M/CSI-H238M/Views/SettingsPage.xaml.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace COFTester.Views
|
||||
{
|
||||
public partial class SettingsPage : UserControl
|
||||
{
|
||||
public SettingsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
212
CSI-H238M/CSI-H238M/Views/TestPage.xaml
Normal file
212
CSI-H238M/CSI-H238M/Views/TestPage.xaml
Normal file
@@ -0,0 +1,212 @@
|
||||
<UserControl x:Class="COFTester.Views.TestPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:scottplot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
||||
Background="Transparent">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 卡片样式 -->
|
||||
<Style x:Key="CardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="15"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="2" Opacity="0.1"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 数字显示样式 -->
|
||||
<Style x:Key="DigitalDisplay" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="42"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="Foreground" Value="#2C3E50"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<SolidColorBrush x:Key="PrimaryBrush" Color="#2C3E50"/>
|
||||
<SolidColorBrush x:Key="AccentBrush" Color="#3498DB"/>
|
||||
<SolidColorBrush x:Key="SuccessBrush" Color="#27AE60"/>
|
||||
<SolidColorBrush x:Key="DangerBrush" Color="#E74C3C"/>
|
||||
<SolidColorBrush x:Key="WarningBrush" Color="#F39C12"/>
|
||||
<SolidColorBrush x:Key="GrayBrush" Color="#7F8C8D"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- 左侧:图表 -->
|
||||
<ColumnDefinition Width="320"/>
|
||||
<!-- 右侧:控制和结果 -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 左侧:图表区域 -->
|
||||
<Border Grid.Column="0" Style="{StaticResource CardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Text="{Binding Lang.FrictionCurve}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}" FontSize="16"/>
|
||||
|
||||
<!-- 试验列表 -->
|
||||
<Border Grid.Row="1" Background="#F8F9FA" CornerRadius="4" Padding="10" Margin="0,0,0,10">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.TestList}" FontWeight="Bold" FontSize="12" Margin="0,0,0,5" Foreground="{StaticResource GrayBrush}"/>
|
||||
<ListBox ItemsSource="{Binding TestRecords}" SelectedItem="{Binding LatestResult}"
|
||||
Background="Transparent" BorderThickness="0" MaxHeight="100">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,2">
|
||||
<CheckBox IsChecked="{Binding IsVisible}" VerticalAlignment="Center" Margin="0,0,5,0"/>
|
||||
<TextBlock Text="{Binding SampleNumber}" FontWeight="Bold" VerticalAlignment="Center" FontSize="12"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 显示全部曲线勾选框 -->
|
||||
<CheckBox Grid.Row="2" Content="{Binding Lang.ShowAllCurves}" IsChecked="{Binding ShowAllCurves}"
|
||||
Margin="0,0,0,10" FontSize="12"/>
|
||||
|
||||
<!-- ScottPlot 实时曲线 -->
|
||||
<scottplot:WpfPlot Grid.Row="3" x:Name="FrictionPlot" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 右侧:控制和结果 -->
|
||||
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<!-- 实时监控 -->
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.RealTimeMonitor}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
<TextBlock Text="{Binding Lang.Force}" FontSize="12" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding CurrentForce, StringFormat={}{0:F4}}" Style="{StaticResource DigitalDisplay}" Foreground="{StaticResource DangerBrush}" FontSize="36"/>
|
||||
<Separator Margin="0,10"/>
|
||||
<TextBlock Text="{Binding Lang.Displacement}" FontSize="12" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding CurrentDisp, StringFormat={}{0:F2}}" Style="{StaticResource DigitalDisplay}" FontSize="28"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 测试控制 -->
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.TestControl}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
|
||||
<Button Content="{Binding Lang.StartTest}" Command="{Binding StartCommand}" Height="80" Foreground="White" FontWeight="Bold" Margin="0,5" FontSize="18">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource SuccessBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
<Button Content="{Binding Lang.Stop}" Command="{Binding StopCommand}" Height="60" Foreground="White" Margin="0,5" FontSize="16">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource DangerBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
<Button Content="{Binding Lang.ResetSystem}" Command="{Binding ResetCommand}" Height="50" Foreground="White" Margin="0,5" FontSize="14">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{StaticResource AccentBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 测试结果 -->
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.TestResults}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
|
||||
<!-- 摩擦系数模式 -->
|
||||
<StackPanel x:Name="FrictionResultsPanel">
|
||||
<StackPanel.Style>
|
||||
<Style TargetType="StackPanel">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Parameters.Standard}" Value="GB/T 2792">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Style>
|
||||
|
||||
<TextBlock Text="{Binding Lang.StaticCOF}" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LatestResult.StaticCOF, StringFormat={}{0:F4}, FallbackValue=--}" FontSize="24" FontWeight="Bold" Foreground="{StaticResource WarningBrush}"/>
|
||||
<Separator Margin="0,8"/>
|
||||
<TextBlock Text="{Binding Lang.KineticCOF}" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LatestResult.KineticCOF, StringFormat={}{0:F4}, FallbackValue=--}" FontSize="24" FontWeight="Bold" Foreground="{StaticResource WarningBrush}"/>
|
||||
<Separator Margin="0,8"/>
|
||||
<TextBlock Text="{Binding Lang.MaxForce}" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LatestResult.MaxForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="18" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 剥离强度模式 -->
|
||||
<StackPanel x:Name="PeelResultsPanel">
|
||||
<StackPanel.Style>
|
||||
<Style TargetType="StackPanel">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Parameters.Standard}" Value="GB/T 2792">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Style>
|
||||
|
||||
<TextBlock Text="{Binding Lang.PeelStrength}" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LatestResult.PeelStrength_N_25mm, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="24" FontWeight="Bold" Foreground="{StaticResource SuccessBrush}"/>
|
||||
<Separator Margin="0,8"/>
|
||||
<TextBlock Text="{Binding Lang.AvgPeelForce}" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LatestResult.AvgKineticForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="24" FontWeight="Bold" Foreground="{StaticResource AccentBrush}"/>
|
||||
<Separator Margin="0,8"/>
|
||||
<TextBlock Text="{Binding Lang.MaxForce}" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LatestResult.MaxForce, StringFormat={}{0:F3}, FallbackValue=--}" FontSize="18" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 快速结果预览 -->
|
||||
<Border Style="{StaticResource CardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Lang.CurrentTest}" FontWeight="Bold" Margin="0,0,0,10" Foreground="{StaticResource GrayBrush}"/>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Lang.DataPoints}" Margin="0,5" FontSize="11"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding DataPointsCount, FallbackValue=0}" FontWeight="Bold" Margin="5,5" HorizontalAlignment="Right" FontSize="11"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding Lang.TestTime}" Margin="0,5" FontSize="11"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LatestResult.TestDateTime, StringFormat={}{0:HH:mm:ss}, FallbackValue=--}" FontWeight="Bold" Margin="5,5" HorizontalAlignment="Right" FontSize="11"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
19
CSI-H238M/CSI-H238M/Views/TestPage.xaml.cs
Normal file
19
CSI-H238M/CSI-H238M/Views/TestPage.xaml.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Windows.Controls;
|
||||
using COFTester.ViewModels;
|
||||
|
||||
namespace COFTester.Views
|
||||
{
|
||||
public partial class TestPage : UserControl
|
||||
{
|
||||
public TestPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void SetViewModel(MainViewModel viewModel)
|
||||
{
|
||||
this.DataContext = viewModel;
|
||||
viewModel.SetPlot(FrictionPlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user