using BDU.Models; using BDU.Tools; using MahApps.Metro.Controls; using MathNet.Numerics; using Microsoft.Win32; using Newtonsoft.Json; using PropertyChanged; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace BDU.Windows { /// /// MainWindow.xaml 的交互逻辑 /// [AddINotifyPropertyChangedInterface] public partial class MainWindow : MetroWindow { public static MainWindow Instance { get; set; } private ProgramModel _program = new(); public ProgramModel Program { get { return _program; } set { _program.StepCollection.CollectionChanged -= StepCollectionIndexChanged; _program = value; _program.StepCollection.CollectionChanged += StepCollectionIndexChanged; } } public UserModel User { get; set; } = new(); public string? CurrentFilePath { get; set; } = ""; public StepModel? SelectedStep { get; set; } public MainWindow() { Instance = this; InitializeComponent(); DataContext = this; User = new() { UserName = "开发者", UserAccount = "Developer", Role = 2 }; } public MainWindow(UserModel user) { Instance = this; InitializeComponent(); DataContext = this; User = user; } private void MetroWindow_Loaded(object sender, RoutedEventArgs e) { Directory.CreateDirectory(SystemConfig.Instance.SystemPath); Program = new(); } #region 辅助方法 /// /// 根据序号重新对步骤进行排序 /// private void ReOrderProgramList() { for (int i = 0; i < Program.StepCollection.Count; i++) { Program.StepCollection[i].Index = i + 1; } } #endregion private void StepCollectionIndexChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Reset || e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Move) { ReOrderProgramList(); } } private void LogOut_Click(object sender, RoutedEventArgs e) { new Login().Show(); this.Close(); } private void UserManage_Click(object sender, RoutedEventArgs e) { if (User.Role != 2) { MessageBox.Show("当前登录用户无权限"); return; } new UsersManage().ShowDialog(); } private Stack _parentProgramStack = new(); private Stack _programPathStack = new(); // 用于显示标题路径 private Stack _currentSubProgramNameStack = new(); // 专门存储当前子程序的名称 private bool _isInSubProgramMode = false; // 添加一个属性来获取当前程序名称(用于显示) public string CurrentProgramDisplayName { get { if (_isInSubProgramMode && _currentSubProgramNameStack.Count > 0) { return _currentSubProgramNameStack.Peek(); } else if (!string.IsNullOrEmpty(CurrentFilePath)) { return System.IO.Path.GetFileName(CurrentFilePath); } return "NewProgram.ats"; // 默认名称 } } public void EnterSubProgramMode(ProgramModel subProgram, string subProgramName, StepModel parentStep) { // 保存当前状态 _parentProgramStack.Push(Program); _programPathStack.Push(Title); // 保存当前标题/路径 _currentSubProgramNameStack.Push(subProgramName); // 保存当前子程序的名称 _parentStepStack.Push(parentStep); // 保存父步骤引用,用于保存时回写 // 进入子程序编辑模式 - 使用传入的 subProgram(确保它是副本) Program = new ProgramModel(subProgram); _isInSubProgramMode = true; // 更新标题显示当前路径 string parentPath = _programPathStack.Count > 0 ? _programPathStack.Peek() : "主程序"; Title = $"{parentPath} > {subProgramName}"; // 通知 StepsManager 更新 Title 显示子程序名称 BDU.Views.StepsManager.Instance?.UpdateTitle(subProgramName); } public void ExitSubProgramMode() { if (_parentProgramStack.Count > 0) { // 先保存当前子程序的更改回父程序的对应步骤 SaveCurrentSubProgramBackToParent(); // 恢复父程序 Program = _parentProgramStack.Pop(); // 恢复其他状态 if (_programPathStack.Count > 0) { Title = _programPathStack.Pop(); } else { Title = "ATS_MainWindow"; } if (_currentSubProgramNameStack.Count > 0) { _currentSubProgramNameStack.Pop(); // 移除当前子程序名称 } if (_parentStepStack.Count > 0) { _parentStepStack.Pop(); // 移除父步骤引用 } _isInSubProgramMode = _parentProgramStack.Count > 0; // 根据栈是否为空判断是否还在子程序模式 // 通知 StepsManager 更新 Title(返回主程序或上一层子程序) if (_isInSubProgramMode && _currentSubProgramNameStack.Count > 0) { // 如果还在子程序模式中(多层嵌套),显示上一层子程序名称 BDU.Views.StepsManager.Instance?.UpdateTitle(_currentSubProgramNameStack.Peek()); } else { // 返回主程序 BDU.Views.StepsManager.Instance?.UpdateTitle(); } } } // 需要一个方法来知道当前编辑的是哪个父步骤的子程序,以便保存 // 我们需要在进入子程序模式时也保存父步骤的引用 private Stack _parentStepStack = new(); // 添加这个栈 private void SaveCurrentSubProgramBackToParent() { if (_parentStepStack.Count > 0) { var parentStep = _parentStepStack.Peek(); if (parentStep.SubProgram != null) { // 将当前编辑的 Program (即子程序) 保存回父步骤的 SubProgram // 注意:这里我们只更新 SubProgram 的内容,不改变其引用 // 如果 SubProgram 有 Name 等元数据,需要单独处理(但根据 ATS 文件结构,似乎没有) parentStep.SubProgram = new ProgramModel(Program); // 创建一个新副本赋值回去 Log.Success($"用户 [ {User.UserName} ] 更新子程序 [ {parentStep.Name} ] "); } } } // 保持这些属性 public bool IsInSubProgramMode => _isInSubProgramMode; public int SubProgramLevel => _parentProgramStack.Count; // 当前嵌套层级 } }