Files
CSI-Z420-Tablet-Multi-Funct…/Views/SettingsWindow.xaml.cs
2026-05-19 16:42:23 +08:00

174 lines
8.2 KiB
C#

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using TabletTester2025.Models;
namespace TabletTester2025
{
public partial class SettingsWindow : Window
{
public SettingsWindow()
{
InitializeComponent();
LoadSettings();
}
private void LoadSettings()
{
var p = App.CurrentPharmaParams;
HardnessMinBox.Text = p.HardnessMin_N.ToString();
HardnessMaxBox.Text = p.HardnessMax_N.ToString();
HardnessCountBox.Text = p.HardnessTestCount.ToString();
FriabilityRpmBox.Text = p.FriabilityTargetRpm.ToString();
FriabilityTimeBox.Text = ResolveFriabilityTargetTimeMin(p).ToString("0.###");
FriabilityRoundsBox.Text = CalculateFriabilityRounds(
ResolveFriabilityTargetTimeMin(p),
p.FriabilityTargetRpm > 0 ? p.FriabilityTargetRpm : 25).ToString();
FriabilityMaxLossBox.Text = p.FriabilityMaxLossPercent.ToString();
SelectDisintegrationDosageForm(p.DisintegrationDosageForm);
DisintegrationMaxSecBox.Text = p.DisintegrationMaxSeconds.ToString();
DisintegrationSpeedBox.Text = p.DisintegrationSpeedRpm.ToString();
DisintegrationTempBox.Text = p.DisintegrationTemperatureC.ToString();
DissolutionMinPercentBox.Text = p.DissolutionMinPercentAt30min.ToString();
DissolutionTempBox.Text = p.DissolutionTemperatureC.ToString();
Dissolution1TimeBox.Text = p.Dissolution1TimeMin.ToString();
Dissolution2TimeBox.Text = p.Dissolution2TimeMin.ToString();
Dissolution1IntervalBox.Text = p.Dissolution1SampleIntervalMin.ToString();
Dissolution2IntervalBox.Text = p.Dissolution2SampleIntervalMin.ToString();
SampleTimesBox.Text = string.Join(",", p.DissolutionSampleTimes);
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
try
{
var p = App.CurrentPharmaParams;
p.HardnessMin_N = double.Parse(HardnessMinBox.Text);
p.HardnessMax_N = double.Parse(HardnessMaxBox.Text);
p.HardnessTestCount = int.Parse(HardnessCountBox.Text);
p.FriabilityTargetRpm = double.Parse(FriabilityRpmBox.Text);
p.FriabilityTargetTimeMin = double.Parse(FriabilityTimeBox.Text);
p.FriabilityTargetRounds = CalculateFriabilityRounds(p.FriabilityTargetTimeMin, p.FriabilityTargetRpm);
p.FriabilityMaxLossPercent = double.Parse(FriabilityMaxLossBox.Text);
p.DisintegrationDosageForm = GetSelectedDisintegrationDosageForm();
p.DisintegrationMaxSeconds = int.Parse(DisintegrationMaxSecBox.Text);
p.DisintegrationSpeedRpm = double.Parse(DisintegrationSpeedBox.Text);
p.DisintegrationTemperatureC = double.Parse(DisintegrationTempBox.Text);
p.DissolutionMinPercentAt30min = double.Parse(DissolutionMinPercentBox.Text);
p.DissolutionTemperatureC = double.Parse(DissolutionTempBox.Text);
p.Dissolution1TimeMin = int.Parse(Dissolution1TimeBox.Text);
p.Dissolution2TimeMin = int.Parse(Dissolution2TimeBox.Text);
p.Dissolution1SampleIntervalMin = double.Parse(Dissolution1IntervalBox.Text);
p.Dissolution2SampleIntervalMin = double.Parse(Dissolution2IntervalBox.Text);
p.DissolutionSampleTimes = SampleTimesBox.Text
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(s => int.Parse(s.Trim()))
.ToArray();
ValidateParameters(p);
App.SaveCurrentPharmaParameters();
MessageBox.Show("参数已保存并立即生效", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
DialogResult = true;
Close();
}
catch (Exception ex)
{
MessageBox.Show($"输入格式错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
private void DisintegrationDosageFormBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (DisintegrationDosageFormBox.SelectedItem is ComboBoxItem item && item.Tag is string seconds)
DisintegrationMaxSecBox.Text = seconds;
}
private void FriabilityCalculationBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (FriabilityRoundsBox == null)
return;
if (int.TryParse(FriabilityTimeBox?.Text, out int timeMin)
&& int.TryParse(FriabilityRpmBox?.Text, out int rpm)
&& timeMin > 0
&& rpm > 0)
{
FriabilityRoundsBox.Text = CalculateFriabilityRounds(timeMin, rpm).ToString();
}
else
{
FriabilityRoundsBox.Text = "";
}
}
private void SelectDisintegrationDosageForm(string dosageForm)
{
foreach (ComboBoxItem item in DisintegrationDosageFormBox.Items)
{
if (string.Equals(item.Content?.ToString(), dosageForm, StringComparison.OrdinalIgnoreCase))
{
DisintegrationDosageFormBox.SelectedItem = item;
return;
}
}
DisintegrationDosageFormBox.SelectedIndex = 0;
}
private string GetSelectedDisintegrationDosageForm()
{
return DisintegrationDosageFormBox.SelectedItem is ComboBoxItem item
? item.Content?.ToString() ?? "普通片"
: "普通片";
}
private static void ValidateParameters(PharmaParameters p)
{
if (p.HardnessMin_N < 0 || p.HardnessMax_N <= p.HardnessMin_N)
throw new InvalidOperationException("硬度内控上限必须大于下限。");
if (p.HardnessTestCount <= 0)
throw new InvalidOperationException("硬度测试次数必须大于0。");
if (p.FriabilityTargetRpm <= 0 || p.FriabilityTargetTimeMin <= 0 || p.FriabilityTargetRounds <= 0 || p.FriabilityMaxLossPercent <= 0)
throw new InvalidOperationException("脆碎度参数必须大于0。");
if (p.DisintegrationMaxSeconds <= 0 || p.DisintegrationSpeedRpm <= 0 || p.DisintegrationTemperatureC <= 0)
throw new InvalidOperationException("崩解参数必须大于0。");
if (p.DissolutionMinPercentAt30min < 0 || p.DissolutionMinPercentAt30min > 150)
throw new InvalidOperationException("溶出度Q值应在0到150之间。");
if (p.DissolutionTemperatureC <= 0 || p.Dissolution1TimeMin <= 0 || p.Dissolution2TimeMin <= 0)
throw new InvalidOperationException("溶出温度和运行时间必须大于0。");
if (p.Dissolution1SampleIntervalMin <= 0 || p.Dissolution2SampleIntervalMin <= 0)
throw new InvalidOperationException("溶出取样间隔必须大于0。");
if (p.DissolutionSampleTimes == null || p.DissolutionSampleTimes.Length == 0 || p.DissolutionSampleTimes.Any(t => t <= 0))
throw new InvalidOperationException("溶出取样时间点必须为大于0的分钟数。");
}
private static double ResolveFriabilityTargetTimeMin(PharmaParameters p)
{
if (p.FriabilityTargetTimeMin > 0)
return p.FriabilityTargetTimeMin;
double rpm = p.FriabilityTargetRpm > 0 ? p.FriabilityTargetRpm : 25;
if (p.FriabilityTargetRounds > 0 && rpm > 0)
return p.FriabilityTargetRounds / rpm;
return 4.0;
}
private static int CalculateFriabilityRounds(double timeMin, double rpm)
{
if (timeMin <= 0 || rpm <= 0)
return 0;
return Math.Max(1, (int)Math.Round(timeMin * rpm, MidpointRounding.AwayFromZero));
}
}
}