using System.IO; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using SparkClient.Model.Common; using SparkClient.Model.Helper; using SparkClient.Model.Services; using SparkClient.Views.Dialog; namespace SparkClient.ViewModel.Grading; public class GradingLoadingVM : BaseViewModel,IDisposable { private double _progress; private SOCClientService _socClientService; /// /// 进度 /// public double Progress { get => _progress; set { _progress = value; OnPropertyChanged(nameof(Progress)); } } public ICommand StopCommand { get; } private string _diamondCode; private string _diamnondType; private bool _disposed; private CancellationTokenSource _progressCts; private CancellationTokenSource? _playbackCts; #region 图片播放控制 private PlayStatus _currentStatus = PlayStatus.Stopped; public PlayStatus CurrentStatus { get => _currentStatus; set { _currentStatus = value; OnPropertyChanged(nameof(CurrentStatus)); OnPropertyChanged(nameof(ButtonText)); // 状态变更时更新按钮文本 } } public string ButtonText => CurrentStatus switch { PlayStatus.Playing => "暂停", PlayStatus.Paused => "继续", _ => "重播" // Stopped 状态 }; private CancellationTokenSource _cts; private int _playDelay = 200; // 默认播放速度 public ICommand PlayControlCommand { get; } public ICommand PreviousCommand { get; } public ICommand NextCommand { get; } private int _currentIndex; public int CurrentIndex { get => _currentIndex; set { _currentIndex = value; OnPropertyChanged(nameof(CurrentIndex)); UpdateCurrentImage(); } } public string[] ImagePaths { get; set; } public ImageSource CurrentImage { get; private set; } public bool ImageIsEnable { get; private set; } #endregion public GradingLoadingVM(string diamnondType, string diamondCode) { _diamondCode = diamondCode; _diamnondType = diamnondType; StopCommand = new RelayCommand(Stop); PlayControlCommand = new RelayCommand(async _ => await HandlePlayControl()); PreviousCommand = new RelayCommand(_ => MovePrevious()); NextCommand = new RelayCommand(_ => MoveNext()); ImageIsEnable = false; _progressCts = new CancellationTokenSource(); _playbackCts = new CancellationTokenSource(); } /// /// 开始检测 /// public async Task Start() { //开始显示进度条 //切工仪通讯 拉取图片 延时...5秒 //播放图片 //图片拉取完毕---| // var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime"); // int iProgTime = int.TryParse(configValue, out var result) ? result : 50000; // int stepTime = iProgTime / 97; // // for (int i = 0; i <= 97; i++) // { // _progressCts.Token.ThrowIfCancellationRequested(); // Progress = i; // await Task.Delay(stepTime, _progressCts.Token); // } var progress = RunProgressAsync(_progressCts.Token); _socClientService = new SOCClientService(); var processImage = _socClientService.ProcessImageCollectionAsync(); //通知页面可以播放图片 await processImage; if (!"ok".Equals(processImage.Result.Status)) { _progressCts.Cancel(); new MessageBox().Show(MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(processImage.Result.Status))); return -1; } LoadImages(processImage.Result.Images); ImageIsEnable = true; await progress; return 0; } private void Stop(object param) { //询问?停止:忽略 } private async Task RunProgressAsync(CancellationToken token) { var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime"); int totalDuration = int.TryParse(configValue, out var result) ? result : 50000; int stepTime = totalDuration / 97; // 使用 IProgress 实现线程安全的进度报告 var progress = new Progress(value => { if (!token.IsCancellationRequested) Progress = value; }); await Task.Run(async () => { for (int i = 0; i <= 97; i++) { token.ThrowIfCancellationRequested(); // 报告进度 ((IProgress)progress).Report(i); // 使用可取消的延迟 await Task.Delay(stepTime, token); } }, token); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { // 取消所有操作 _progressCts?.Cancel(); _playbackCts?.Cancel(); // 释放托管资源 _progressCts?.Dispose(); _playbackCts?.Dispose(); } _disposed = true; } #region 图片播放处理 public void LoadImages(string folderPath) { ImagePaths = Directory.GetFiles(folderPath, "*.bmp"); CurrentIndex = 0; CurrentStatus = PlayStatus.Stopped; } public void LoadImages(List folderPath) { ImagePaths = folderPath.ToArray(); CurrentIndex = 0; CurrentStatus = PlayStatus.Stopped; } private async Task HandlePlayControl() { switch (CurrentStatus) { case PlayStatus.Stopped: await StartPlayback(); // 开始或重播 break; case PlayStatus.Playing: PausePlayback(); // 暂停 break; case PlayStatus.Paused: await ResumePlayback();// 继续 break; } } private async Task StartPlayback() { CurrentStatus = PlayStatus.Playing; _cts = new CancellationTokenSource(); try { for (CurrentIndex = 0; CurrentIndex < ImagePaths.Length; CurrentIndex++) { if (_cts.Token.IsCancellationRequested) break; await Task.Delay(_playDelay); } // 播放完成处理 if (CurrentIndex >= ImagePaths.Length) { CurrentStatus = PlayStatus.Stopped; CurrentIndex = 0; // 重置为初始位置 } } catch (TaskCanceledException) { /* 正常取消处理 */ } } private void PausePlayback() { _cts?.Cancel(); CurrentStatus = PlayStatus.Paused; } private async Task ResumePlayback() { CurrentStatus = PlayStatus.Playing; _cts = new CancellationTokenSource(); await StartPlayback(); } private void UpdateCurrentImage() { if (ImagePaths == null || CurrentIndex < 0 || CurrentIndex >= ImagePaths.Length) return; var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.UriSource = new Uri(ImagePaths[CurrentIndex]); bitmap.EndInit(); bitmap.Freeze(); // 确保跨线程安全 CurrentImage = bitmap; OnPropertyChanged(nameof(CurrentImage)); } private void MovePrevious() { if (CurrentStatus == PlayStatus.Playing) PausePlayback(); CurrentIndex = (CurrentIndex - 1 + ImagePaths.Length) % ImagePaths.Length; } private void MoveNext() { if (CurrentStatus == PlayStatus.Playing) PausePlayback(); CurrentIndex = (CurrentIndex + 1) % ImagePaths.Length; } #endregion } public enum PlayStatus { Stopped, // 初始/停止状态 Playing, // 播放中 Paused // 暂停中 }