using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace _29WxOrderWpf.Ctrls.OrderCtrls; public partial class OrderListCtrl : INotifyPropertyChanged { #region NotifayProperty /// /// Occurs when a property value changes. /// public event PropertyChangedEventHandler PropertyChanged; /// /// Checks if a property already matches a desired value. Sets the property and /// notifies listeners only when necessary. /// /// Type of the property. /// Reference to a property with both getter and setter. /// Desired value for the property. /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers that /// support CallerMemberName. /// True if the value was changed, false if the existing value matched the /// desired value. protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; storage = value; RaisePropertyChanged(propertyName); return true; } /// /// Checks if a property already matches a desired value. Sets the property and /// notifies listeners only when necessary. /// /// Type of the property. /// Reference to a property with both getter and setter. /// Desired value for the property. /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers that /// support CallerMemberName. /// Action that is called after the property value has been changed. /// True if the value was changed, false if the existing value matched the /// desired value. protected virtual bool SetProperty(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; storage = value; onChanged?.Invoke(); RaisePropertyChanged(propertyName); return true; } /// /// Raises this object's PropertyChanged event. /// /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers /// that support . protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } /// /// Raises this object's PropertyChanged event. /// /// The PropertyChangedEventArgs protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { PropertyChanged?.Invoke(this, args); } #endregion private string _bottomMsg = ""; public string BottomMsg { get => _bottomMsg; set => SetProperty(ref _bottomMsg, value); } private double _progressValue; public double ProgressValue { get => _progressValue; set => SetProperty(ref _progressValue, value); } private double _progressMaximum = 100; public double ProgressMaximum { get => _progressMaximum; set => SetProperty(ref _progressMaximum, value); } public void SetProgress(int value, int maxValue) { StopUnknownTotalProgressTimer(); ProgressValue = value; ProgressMaximum = maxValue; } #region 未知总数百分比模拟进度 private System.Threading.Timer _unknownTotalProgressTimer; private DateTime _unknownTotalProgressStartTime; /// /// 开始未知总数的百分比模拟进度:80% 之前走得快,越到最后走得越慢, /// 理论上永远走不到 95% 以上,直到调用 才会变成 100%。 /// public void StartProgress() { StopUnknownTotalProgressTimer(); ProgressMaximum = 100; ProgressValue = 0; _unknownTotalProgressStartTime = DateTime.Now; _unknownTotalProgressTimer = new System.Threading.Timer(_ => UpdateUnknownTotalProgress(), null, 0, 200); } /// /// 结束进度:停止模拟,进度条立即变为 100%。 /// public void CompleteProgress() { StopUnknownTotalProgressTimer(); ProgressMaximum = 100; ProgressValue = 100; } private void UpdateUnknownTotalProgress() { try { Dispatcher.BeginInvoke(new Action(() => { var elapsed = (DateTime.Now - _unknownTotalProgressStartTime).TotalSeconds; double progress; if (elapsed <= 10) { // 前 10 秒内快速推进到 80% progress = Math.Max(0, Math.Min(80, elapsed * 8)); } else { // 超过 80% 后指数衰减越来越慢,渐近线为 95%,理论上永远走不到 95% 以上 progress = 95.0 - 15.0 * Math.Exp(-(elapsed - 10.0) / 20.0); } if (progress > 95) progress = 95; ProgressValue = progress; })); } catch { } } private void StopUnknownTotalProgressTimer() { if (_unknownTotalProgressTimer == null) return; try { _unknownTotalProgressTimer.Dispose(); } catch { } _unknownTotalProgressTimer = null; } #endregion }