feat: 基础信息叠板计算功能

- 新增 StackCountCalculator: 数字化规则表(短槽刀/EA刀10×4、槽刀10×4、钻针10×6),公开Calculate方法,输入校验,查表逻辑,16oz铜厚递减
- 新增 StartupSelectionViewModel: 替换匿名DataContext,保留所有显示属性,新增板厚/铜厚输入、计算结果/明细、CanCalculate
- 新增 NonEmptyToVisibilityConverter
- 修改 StartupSelectionWindow.xaml: 增宽680px,新增3行(输入+结果+明细),计算按钮在基础信息内部
- 修改 StartupSelectionWindow.xaml.cs: 构造函数接收ViewModel,新增计算按钮事件
- 修改 App.xaml.cs: 构建ViewModel实例,CalculateStackMinDiameters独立遍历Tools(含0.749mm,排除机台码)
- 修改 App.xaml: 注册NonEmptyToVisibilityConverter
This commit is contained in:
2026-06-27 16:24:45 +08:00
parent e27636dd93
commit fa697c9fd0
7 changed files with 919 additions and 31 deletions

View File

@@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
namespace DrillTools
{
/// <summary>
/// 启动选择窗口的 ViewModel承载基础信息显示和叠板计算
/// </summary>
public class StartupSelectionViewModel : INotifyPropertyChanged
{
#region
private string _fileName = string.Empty;
/// <summary>
/// 文件名(不含扩展名)
/// </summary>
public string FileName
{
get => _fileName;
set => SetProperty(ref _fileName, value);
}
private double _minDrillDiameter;
/// <summary>
/// 最小钻咀直径(显示用,已排除 0.749mm
/// </summary>
public double MinDrillDiameter
{
get => _minDrillDiameter;
set => SetProperty(ref _minDrillDiameter, value);
}
private double _minSlotDiameter;
/// <summary>
/// 最小槽刀直径(显示用)
/// </summary>
public double MinSlotDiameter
{
get => _minSlotDiameter;
set => SetProperty(ref _minSlotDiameter, value);
}
private double _minEADiameter;
/// <summary>
/// 最小EA刀直径显示用
/// </summary>
public double MinEADiameter
{
get => _minEADiameter;
set => SetProperty(ref _minEADiameter, value);
}
private bool _isPpDrillTape;
/// <summary>
/// 是否为 PP 钻带
/// </summary>
public bool IsPpDrillTape
{
get => _isPpDrillTape;
set => SetProperty(ref _isPpDrillTape, value);
}
private double _ppXSpacing;
/// <summary>
/// PP X 间距
/// </summary>
public double PpXSpacing
{
get => _ppXSpacing;
set => SetProperty(ref _ppXSpacing, value);
}
private double _ppYSpacing;
/// <summary>
/// PP Y 间距
/// </summary>
public double PpYSpacing
{
get => _ppYSpacing;
set => SetProperty(ref _ppYSpacing, value);
}
private bool _hasOuter3175Spacing;
/// <summary>
/// 是否有 3.175 外围孔间距
/// </summary>
public bool HasOuter3175Spacing
{
get => _hasOuter3175Spacing;
set => SetProperty(ref _hasOuter3175Spacing, value);
}
private double _outer3175XSpacing;
/// <summary>
/// 3.175 外围孔 X 间距
/// </summary>
public double Outer3175XSpacing
{
get => _outer3175XSpacing;
set => SetProperty(ref _outer3175XSpacing, value);
}
private double _outer3175YSpacing;
/// <summary>
/// 3.175 外围孔 Y 间距
/// </summary>
public double Outer3175YSpacing
{
get => _outer3175YSpacing;
set => SetProperty(ref _outer3175YSpacing, value);
}
#endregion
#region
private string _boardThicknessInput = string.Empty;
/// <summary>
/// 板厚输入(原始文本)
/// </summary>
public string BoardThicknessInput
{
get => _boardThicknessInput;
set
{
if (SetProperty(ref _boardThicknessInput, value))
UpdateCanCalculate();
}
}
private string _copperThicknessInput = string.Empty;
/// <summary>
/// 铜厚输入(原始文本,单位 oz
/// </summary>
public string CopperThicknessInput
{
get => _copperThicknessInput;
set
{
if (SetProperty(ref _copperThicknessInput, value))
UpdateCanCalculate();
}
}
private string _stackCountResult = string.Empty;
/// <summary>
/// 叠板计算结果文本(如"建议叠板4 张"或错误提示)
/// </summary>
public string StackCountResult
{
get => _stackCountResult;
set => SetProperty(ref _stackCountResult, value);
}
private string _stackCountDetail = string.Empty;
/// <summary>
/// 叠板计算明细文本
/// </summary>
public string StackCountDetail
{
get => _stackCountDetail;
set => SetProperty(ref _stackCountDetail, value);
}
private bool _canCalculate;
/// <summary>
/// 是否可以执行计算(板厚和铜厚都已输入有效数字)
/// </summary>
public bool CanCalculate
{
get => _canCalculate;
set => SetProperty(ref _canCalculate, value);
}
#endregion
#region 0.749mm
/// <summary>
/// 叠板计算用的最小钻针直径(包含 0.749mm,由调用方遍历 Tools 独立计算)
/// </summary>
public double StackCalcMinDrill { get; set; }
/// <summary>
/// 叠板计算用的最小槽刀直径(包含 0.749mm 的槽刀,由调用方独立计算)
/// </summary>
public double StackCalcMinSlot { get; set; }
/// <summary>
/// 叠板计算用的最小EA刀直径由调用方独立计算
/// </summary>
public double StackCalcMinEA { get; set; }
#endregion
#region
/// <summary>
/// 执行叠板计算(由按钮点击转调)
/// </summary>
public void CalculateStackCount()
{
// 解析输入
if (!double.TryParse(BoardThicknessInput, out double boardThickness) ||
!double.TryParse(CopperThicknessInput, out double copperThickness))
{
StackCountResult = "请输入有效的板厚和铜厚数字";
StackCountDetail = string.Empty;
return;
}
// 调用计算器
var result = StackCountCalculator.Calculate(
boardThickness, copperThickness,
StackCalcMinDrill, StackCalcMinSlot, StackCalcMinEA);
if (result.Success)
{
StackCountResult = $"建议叠板:{result.RecommendedCount} 张";
StackCountDetail = result.Detail;
}
else
{
StackCountResult = "无法计算";
StackCountDetail = string.IsNullOrEmpty(result.Detail)
? result.Message
: $"{result.Message}\n{result.Detail}";
}
}
/// <summary>
/// 更新 CanCalculate 状态(板厚和铜厚均为大于 0 的数字时可用)
/// </summary>
private void UpdateCanCalculate()
{
CanCalculate = double.TryParse(BoardThicknessInput, out double bt) && bt > 0 &&
double.TryParse(CopperThicknessInput, out double ct) && ct > 0;
}
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}