Files
HeadgearViewingRange3M/ViewModels/TestViewModel.cs
2026-04-01 20:29:45 +08:00

263 lines
7.0 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Windows.Forms;
using System.Windows.Threading;
namespace MembranePoreTester
{
public partial class TestViewModel : ObservableObject
{
private readonly DispatcherTimer _angleUpdateTimer;
private bool _isTestRunning;
public TestViewModel()
{
_angleUpdateTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(100)
};
_angleUpdateTimer.Tick += AngleUpdateTimer_Tick;
// 默认值
ResolutionAngle = 0.1;
RotationSpeed = 30;
LeftEyeCoeff = 1.0;
RightEyeCoeff = 1.0;
RetentionCorrectionCoeff = 1.0;
IsSampleMode = true;
}
// 当前模式显示文本
[ObservableProperty]
private string _currentMode = "试样测试";
// 模式切换
private bool _isBlankMode;
public bool IsBlankMode
{
get => _isBlankMode;
set
{
if (SetProperty(ref _isBlankMode, value) && value)
{
CurrentMode = "空白模式";
IsSampleMode = false;
OnModeChanged();
}
}
}
private bool _isSampleMode;
public bool IsSampleMode
{
get => _isSampleMode;
set
{
if (SetProperty(ref _isSampleMode, value) && value)
{
CurrentMode = "试样测试";
IsBlankMode = false;
OnModeChanged();
}
}
}
// 参数设置
[ObservableProperty]
private double _resolutionAngle;
[ObservableProperty]
private double _rotationSpeed;
[ObservableProperty]
private double _currentAngle;
// 视野面积数据
[ObservableProperty]
private double _leftEyeArea;
[ObservableProperty]
private double _rightEyeArea;
[ObservableProperty]
private double _binocularArea;
[ObservableProperty]
private double _lowerField;
[ObservableProperty]
private double _blankArea;
[ObservableProperty]
private double _fieldRetentionRate;
// 灯条数据
[ObservableProperty]
private double _upperLampData;
[ObservableProperty]
private double _middleLampData;
[ObservableProperty]
private double _lowerLampData;
// 面积系数
[ObservableProperty]
private double _leftEyeCoeff;
[ObservableProperty]
private double _rightEyeCoeff;
[ObservableProperty]
private double _retentionCorrectionCoeff;
// 命令
[RelayCommand]
private void Reset()
{
CurrentAngle = 0;
// 用户在此添加硬件复位代码
}
[RelayCommand]
private void OpenLeftEye()
{
// 用户实现左眼开逻辑
UpdateLeftEyeArea();
}
[RelayCommand]
private void OpenRightEye()
{
// 用户实现右眼开逻辑
UpdateRightEyeArea();
}
[RelayCommand]
private void Reverse()
{
// 反转方向
RotationSpeed = -Math.Abs(RotationSpeed);
}
[RelayCommand]
private void Forward()
{
// 正转方向
RotationSpeed = Math.Abs(RotationSpeed);
}
[RelayCommand]
private void StartTest()
{
if (_isTestRunning) return;
_isTestRunning = true;
_angleUpdateTimer.Start();
}
[RelayCommand]
private void StopTest()
{
_isTestRunning = false;
_angleUpdateTimer.Stop();
}
// 导航命令(供用户跳转页面)
[RelayCommand]
private void NavigateHome()
{
// 用户实现:关闭当前窗口或切换主窗口内容
}
[RelayCommand]
private void NavigateTest()
{
// 已在测试界面,可忽略
}
[RelayCommand]
private void NavigateData()
{
// 跳转到数据记录界面
}
[RelayCommand]
private void NavigateRecord()
{
// 跳转到记录画面
}
// 内部辅助方法
private void OnModeChanged()
{
if (IsBlankMode)
{
BlankArea = 0;
FieldRetentionRate = 0;
}
else
{
CalculateFieldAreas();
}
}
private void AngleUpdateTimer_Tick(object sender, EventArgs e)
{
if (!_isTestRunning) return;
// 模拟角度变化
CurrentAngle += RotationSpeed * 0.1;
if (CurrentAngle >= 360) CurrentAngle -= 360;
if (CurrentAngle < 0) CurrentAngle += 360;
CalculateFieldAreas();
UpdateLampData();
}
private void CalculateFieldAreas()
{
double angle = CurrentAngle;
LeftEyeArea = Math.Round(50 + 30 * Math.Sin(angle * Math.PI / 180) * LeftEyeCoeff, 3);
RightEyeArea = Math.Round(50 + 30 * Math.Cos(angle * Math.PI / 180) * RightEyeCoeff, 3);
BinocularArea = Math.Round(LeftEyeArea + RightEyeArea - 20, 3);
LowerField = Math.Round(30 + 20 * Math.Sin(angle * Math.PI / 180), 1);
if (IsBlankMode)
{
BlankArea = Math.Round(10 + 5 * Math.Sin(angle * Math.PI / 180), 3);
FieldRetentionRate = BinocularArea > 0
? Math.Round((BinocularArea - BlankArea) / BinocularArea * 100, 2)
: 0;
}
else
{
FieldRetentionRate = Math.Round(BinocularArea / 100 * 100 * RetentionCorrectionCoeff, 2);
if (FieldRetentionRate > 100) FieldRetentionRate = 100;
if (FieldRetentionRate < 0) FieldRetentionRate = 0;
}
}
private void UpdateLeftEyeArea()
{
LeftEyeArea = Math.Round(LeftEyeArea + 5, 3);
if (LeftEyeArea > 100) LeftEyeArea = 100;
CalculateFieldAreas();
}
private void UpdateRightEyeArea()
{
RightEyeArea = Math.Round(RightEyeArea + 5, 3);
if (RightEyeArea > 100) RightEyeArea = 100;
CalculateFieldAreas();
}
private void UpdateLampData()
{
Random rand = new Random();
UpperLampData = Math.Round(rand.NextDouble() * 100, 2);
MiddleLampData = Math.Round(rand.NextDouble() * 100, 2);
LowerLampData = Math.Round(rand.NextDouble() * 100, 2);
}
}
}