- 新增 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
267 lines
7.8 KiB
C#
267 lines
7.8 KiB
C#
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
|
||
}
|
||
}
|