using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; namespace RecipeEditorLib.RecipeModel.Params { public sealed class RecipeStepCollection : ObservableCollection { #region Variables private bool _isSaved; private bool _isHideValue; #endregion #region Constructors public RecipeStepCollection() { _isSaved = true; } public RecipeStepCollection(IEnumerable steps) : base(steps) { _isSaved = true; } #endregion #region Properties /// /// 返回当前配方是否已经被保存。 /// public bool IsSaved { get => _isSaved; set { _isSaved = value; OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsSaved))); } } /// /// 返回被选中的配方步骤。 /// public IReadOnlyList SelectedSteps => this.ToList().Where(x => x.StepNoParam != null && x.StepNoParam.IsChecked).ToList(); /// /// 返回是否隐藏所有步骤的参数值。 /// public bool IsHideValue { get => _isHideValue; set { _isHideValue = value; this.ToList().ForEach(x => x.IsHideValue = value); } } #endregion #region Methods /// /// 当配方中的某步骤的IsSaved状态发生变化时,触发此事件。 /// /// /// private void ItemOnSavedStateChanged(object sender, bool e) { if (e == false) IsSaved = false; else IsSaved = (this.ToList().FirstOrDefault(x => x.IsSaved == false) == null); } /// /// 更新Step序列号。 /// /// public void UpdateStepIndex(bool MarkAsSaved = false) { var step = this.FirstOrDefault(); if(!(step?.FirstOrDefault(x => x is StepParam) is StepParam stepNoParam)) return; var index = 1; while (true) { stepNoParam.Value = index; if(MarkAsSaved) stepNoParam.Save(); //! 最后一个步骤的Next应该为Null,此时跳出循环。 if (stepNoParam.Next is StepParam nextParam) stepNoParam = nextParam; else break; index++; } } /// /// 保存当前配方。 /// public void Save() { this.ToList().ForEach(x => x.Save()); } /// /// 取消所有参数的Highlight状态。 /// public void ResetHighlight() { this.ToList().ForEach(x => x.ResetHighlight()); } #endregion #region Overrided Methods /// /// /// /// /// private static void LinkSteps(RecipeStep previous, RecipeStep next) { if (previous != null && next != null) { previous.SetNextStep(next); next.SetPreviousStep(previous); } else if (previous == null && next != null) { next.SetPreviousStep(null); } else { previous?.SetNextStep(null); } } protected override void SetItem(int index, RecipeStep item) { throw new NotSupportedException(); } protected override void InsertItem(int index, RecipeStep item) { base.InsertItem(index, item); if (item != null) { item.Parent = this; item.SavedStateChanged += ItemOnSavedStateChanged; if (index > 0 && index < Count - 1) { LinkSteps(this[index - 1], this[index]); LinkSteps(this[index], this[index + 1]); } else if (index == 0) { if (Count > 1) { LinkSteps(null, this[index]); LinkSteps(this[index], this[index + 1]); } else { LinkSteps(null, this[index]); LinkSteps(this[index], null); } } else if (index == Count - 1) { LinkSteps(this[index - 1], this[index]); LinkSteps(this[index], null); } } UpdateStepIndex(); this[index].Validate(); } protected override void RemoveItem(int index) { if (Count > 0) { if (index >= 0 && index < Count) { this[index].SavedStateChanged -= ItemOnSavedStateChanged; } } IsSaved = false; // 将前后两个Param链接起来 var preStep = this[index].Previous; var nextStep = this[index].Next; LinkSteps(preStep, nextStep); preStep?.Validate(); nextStep?.Validate(); base.RemoveItem(index); UpdateStepIndex(); } protected override void ClearItems() { if (Count > 0) { this.ToList().ForEach(x => x.SavedStateChanged -= ItemOnSavedStateChanged); IsSaved = false; } else { IsSaved = true; } base.ClearItems(); } protected override void MoveItem(int oldIndex, int newIndex) { throw new NotSupportedException(); } #endregion } }