diff --git a/App.config b/App.config index 4de78d0..52904f6 100644 --- a/App.config +++ b/App.config @@ -2,8 +2,8 @@ - - + + diff --git a/App.xaml b/App.xaml index 3c99c29..8bd02e3 100644 --- a/App.xaml +++ b/App.xaml @@ -74,6 +74,9 @@ + + + diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml index 9dc7086..1fd7b07 100644 --- a/Language/zh_CN.xaml +++ b/Language/zh_CN.xaml @@ -228,4 +228,7 @@ 未找到Nvidia显卡驱动,部分功能可能无法正常运行。 Nvidia显卡驱动版本过旧,请尝试升级显卡驱动。(当前:%version,最低:528.33) + 正在检测,请稍等 + 终止检测 + \ No newline at end of file diff --git a/Model/Helper/ConfigurationHelper.cs b/Model/Helper/ConfigurationHelper.cs index 26705d0..9176078 100644 --- a/Model/Helper/ConfigurationHelper.cs +++ b/Model/Helper/ConfigurationHelper.cs @@ -13,9 +13,16 @@ public class ConfigurationHelper public static string ReadConfigValue(string key) { - string name = config.AppSettings.Settings[key].Value; + try + { + string name = config.AppSettings.Settings[key].Value; - return name; + return name; + } + catch (Exception e) + { + return ""; + } } /// /// 写入配置 diff --git a/ViewModel/BaseWindow/BaseControlVM.cs b/ViewModel/BaseWindow/BaseControlVM.cs index 5c58e27..5421205 100644 --- a/ViewModel/BaseWindow/BaseControlVM.cs +++ b/ViewModel/BaseWindow/BaseControlVM.cs @@ -18,6 +18,7 @@ public class BaseControlVM : BaseViewModel public string WindowTitle { get { return _windowTitle; } set { _windowTitle = value; OnPropertyChanged("WindowTitle"); } } public Visibility ShowFunctionButton { get { return _showFunctionButton; } set { _showFunctionButton = value; OnPropertyChanged("ShowFunctionButton"); } } + public Visibility ShowCloseButton { get { return _showFunctionButton; } set { _showFunctionButton = value; OnPropertyChanged("ShowFunctionButton"); } } public string FunctionButtonIcon { get { return _functionButtonIcon; } set { _functionButtonIcon = value; OnPropertyChanged("FunctionButtonIcon"); } } public Object ViewControl { get { return _viewContent; } set { _viewContent = value; OnPropertyChanged("ViewControl"); } } @@ -55,6 +56,7 @@ public class BaseControlVM : BaseViewModel Content = vm; WindowTitle = windowTitle; ShowFunctionButton = Visibility.Hidden; + ShowCloseButton = Visibility.Visible; CloseCommand = new RelayCommand(CloseVM); NextCommand = new RelayCommand(NextDiamond); @@ -80,11 +82,9 @@ public class BaseControlVM : BaseViewModel } }); } - else + else if(vm.GetType().Equals(typeof(GradingLoadingVM))) { - // _hotKeyManager = new HotKeyManager(); - // var hotKey = new HotKey(Key.R, ModifierKeys.Control | ModifierKeys.Alt); - // _hotKeyManager.Unregister(hotKey); + ShowCloseButton = Visibility.Hidden; } } diff --git a/ViewModel/Grading/DiamondSelectVM.cs b/ViewModel/Grading/DiamondSelectVM.cs index 752de0d..ce2934e 100644 --- a/ViewModel/Grading/DiamondSelectVM.cs +++ b/ViewModel/Grading/DiamondSelectVM.cs @@ -144,9 +144,30 @@ public class DiamondSelectVM : BaseViewModel { DiamondCode = ""; } + + var loadingView = new GradingLoadingVM(param.ToString(), DiamondCode); + BaseControlVM vm = new BaseControlVM(loadingView, MultilingualHelper.getString("DetectionResult")); + vm.WindowTitle = string.IsNullOrWhiteSpace(DiamondCode) ? vm.WindowTitle : $"{vm.WindowTitle} - {DiamondCode}"; + WindowManager.mainViewModel.Content = vm; + WindowManager.openContent.Add(vm); + + int res = await loadingView.Start(); + + if (res < 0) + { + //返回 + loadingView.Dispose(); + WindowManager.mainViewModel.Content = WindowManager.PreviousVM(); + ; + return; + } + else + { + //获取结果,下一步 + } #if DEBUG - DoStartGrading(param); -#else + //DoStartGrading(param); +//#else LoadingDialog loading = new LoadingDialog(DiamondCode); try { diff --git a/ViewModel/Grading/GradingLoadingVM.cs b/ViewModel/Grading/GradingLoadingVM.cs new file mode 100644 index 0000000..bd65506 --- /dev/null +++ b/ViewModel/Grading/GradingLoadingVM.cs @@ -0,0 +1,300 @@ +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 // 暂停中 +} \ No newline at end of file diff --git a/Views/BaseWindow/BaseControl.xaml b/Views/BaseWindow/BaseControl.xaml index f955eb5..3a26943 100644 --- a/Views/BaseWindow/BaseControl.xaml +++ b/Views/BaseWindow/BaseControl.xaml @@ -157,7 +157,7 @@ Background="Transparent" Padding="0" > - diff --git a/Views/Grading/GradingLoading.xaml b/Views/Grading/GradingLoading.xaml index 44c9997..065665e 100644 --- a/Views/Grading/GradingLoading.xaml +++ b/Views/Grading/GradingLoading.xaml @@ -10,6 +10,7 @@ mc:Ignorable="d" d:DesignWidth="1920" d:DesignHeight="600" + Loaded="GradingLoading_OnLoaded" >