HashCalculator.GUI/CopyableBox.xaml.cs

157 lines
4.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// CopyableBox.xaml 的交互逻辑
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1812")]
internal partial class CopyableBox : Window, IDisposable
{
private CopyableBoxViewModel ViewModel => (CopyableBoxViewModel)DataContext;
public static void ShowDialog(Func<CancellationToken, Task<string>> 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<CopyableBox> CloseCommand { get; }
public CopyableBoxViewModel()
{
CopyCommand = new Command(() =>
{
Clipboard.SetText(Text);
return Task.CompletedTask;
});
CloseCommand = new Command<CopyableBox>(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<CancellationToken, Task<string>> action, Dispatcher dispatcher)
{
_task = InitializationTask(action, dispatcher);
}
private async Task InitializationTask(Func<CancellationToken, Task<string>> action, Dispatcher dispatcher)
{
var token = _cancellationTokenSource.Token;
async Task<string> 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();
}
}
}