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(string title, Func> action) { using var box = new CopyableBox(); box.ViewModel.Initialize(title, action, box.Dispatcher); box.Owner = App.Current.MainWindow; 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; private string _title = "我居然没有名字qwq"; public string Title { get => _title; private set => SetField(ref _title, value); } private 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(string title, Func> action, Dispatcher dispatcher) { Title = title; _task = InitializationTask(action, dispatcher); } private async Task InitializationTask(Func> action, Dispatcher dispatcher) { var token = _cancellationTokenSource.Token; async Task Action() { try { using var timer = new DisposableDispatcherTimer(timer => { Text = $"{InitialMessage}\r\n目前耗时{timer.TimeSinceCreation},稍微再等一下吧233"; }, dispatcher, TimeSpan.FromMilliseconds(200), TimeSpan.FromSeconds(1)); return await action(token).ConfigureAwait(false); } catch (OperationCanceledException) { return "操作已被取消"; } } Text = await dispatcher.Invoke(Action).ConfigureAwait(true); } private void Cancel() { _cancellationTokenSource.Cancel(); } } }