263 lines
7.0 KiB
C#
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);
|
|
}
|
|
}
|
|
} |