using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading; 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; using System.Windows.Threading; using TechnologyAssembler.Core.Extensions; namespace HashCalculator.GUI { /// /// CopyableBox.xaml 的交互逻辑 /// [SuppressMessage("Microsoft.Performance", "CA1812")] internal partial class CopyableBox : Window, IDisposable { private CopyableBoxViewModel ViewModel => (CopyableBoxViewModel)DataContext; public static void ShowDialog(Func> action) { using var box = new CopyableBox(); box.ViewModel.Initialize(action, box.Dispatcher); box.ShowDialog(); } private CopyableBox() { InitializeComponent(); } public void Dispose() { ViewModel.Dispose(); } private void ClosingHandler(object sender, CancelEventArgs e) { if (ViewModel.ReadyToClose) { return; } e.Cancel = true; if (ViewModel.CloseCommand.CanExecuteValue) { ViewModel.CloseCommand.Execute(this); } return; } } [SuppressMessage("Microsoft.Performance", "CA1812")] internal class CopyableBoxViewModel : NotifyPropertyChanged, IDisposable { private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private Task? _task; public const string InitialMessage = "正在加载…… 关闭窗口就可以取消加载("; private string _text = InitialMessage; public string Text { get => _text; private set => SetField(ref _text, value); } public string CloseButtonText => CloseCommand.CanExecuteValue ? "关闭窗口" : "正在关闭…"; private bool _readyToClose = false; public bool ReadyToClose { get => _readyToClose; private set => SetField(ref _readyToClose, value); } public Command CopyCommand { get; } public Command CloseCommand { get; } public CopyableBoxViewModel() { CopyCommand = new Command(() => { Clipboard.SetText(Text); return Task.CompletedTask; }); CloseCommand = new Command(async window => { CloseCommand.CanExecuteValue = false; Notify(nameof(CloseButtonText)); if (_task != null) { try { Cancel(); await _task.ConfigureAwait(true); } catch (OperationCanceledException) { } } ReadyToClose = true; window.Close(); }); } public void Dispose() { Cancel(); _cancellationTokenSource.Dispose(); } public void Initialize(Func> action, Dispatcher dispatcher) { _task = InitializationTask(action, dispatcher); } private async Task InitializationTask(Func> action, Dispatcher dispatcher) { var utcBegin = DateTimeOffset.UtcNow; var timer = new DispatcherTimer(TimeSpan.FromMilliseconds(200), DispatcherPriority.Normal, (s, e) => { var timeElapsed = DateTimeOffset.UtcNow - utcBegin; if (((DispatcherTimer)s).IsEnabled && timeElapsed.TotalSeconds > 1) { Text = Text = $"{InitialMessage}\r\n目前耗时{timeElapsed},稍微再等一下吧233"; } }, dispatcher); timer.Start(); var token = _cancellationTokenSource.Token; async Task Action() { try { return await action(token).ConfigureAwait(false); } catch (OperationCanceledException) { return "操作已被取消"; } finally { timer.Stop(); } } Text = await dispatcher.Invoke(Action).ConfigureAwait(true); } private void Cancel() { _cancellationTokenSource.Cancel(); } } }