试图修弹窗崩溃

This commit is contained in:
lanyi 2022-01-25 21:59:01 +01:00
parent ce26ef298e
commit 9e416390eb
4 changed files with 71 additions and 55 deletions

View File

@ -42,7 +42,7 @@ namespace HashCalculator.GUI
{ {
case InputEntryType.BinaryFile: case InputEntryType.BinaryFile:
ViewModel.StatusText = "请留意一下弹出的窗口("; ViewModel.StatusText = "请留意一下弹出的窗口(";
CopyableBox.ShowDialog("SAGE FastHash 计算器", token => CalculateBinaryHash(selected.Value, token)); await ViewModel.RequestCopyableBox("SAGE FastHash 计算器", token => CalculateBinaryHash(selected.Value, token));
ViewModel.StatusText = string.Empty; ViewModel.StatusText = string.Empty;
return; return;
case InputEntryType.BigFile: case InputEntryType.BigFile:
@ -62,7 +62,7 @@ namespace HashCalculator.GUI
catch (Exception error) catch (Exception error)
{ {
ViewModel.StatusText = "失败…"; ViewModel.StatusText = "失败…";
CopyableBox.ShowDialog("SAGE FastHash 计算器 - 失败!", _ => await ViewModel.RequestCopyableBox("SAGE FastHash 计算器 - 失败!", _ =>
{ {
return Task.FromResult($"在尝试加载 {selected.Type} `{selected.Value}` 时发生错误:\r\n{error}"); return Task.FromResult($"在尝试加载 {selected.Type} `{selected.Value}` 时发生错误:\r\n{error}");
}); });
@ -313,7 +313,7 @@ namespace HashCalculator.GUI
} }
} }
public static async Task LoadCsf(string filePath) public async Task LoadCsf(string filePath)
{ {
await ExceptionWrapepr(async () => await ExceptionWrapepr(async () =>
{ {
@ -417,7 +417,22 @@ namespace HashCalculator.GUI
UpdateEntries(); UpdateEntries();
} }
public static IEnumerable<InputEntry> FindManifests() private async Task ExceptionWrapepr(Func<Task> action, string errorTitle, string preErrorMessage)
{
try
{
await action().ConfigureAwait(true);
}
catch (Exception exception)
{
await ViewModel.RequestCopyableBox(errorTitle, _ =>
{
return Task.FromResult(preErrorMessage + exception);
});
}
}
private static IEnumerable<InputEntry> FindManifests()
{ {
var manifests = VirtualFileSystem.ListFiles(SelectedFileSystemRootPath, "*.manifest", VirtualSearchOptionType.AllDirectories); var manifests = VirtualFileSystem.ListFiles(SelectedFileSystemRootPath, "*.manifest", VirtualSearchOptionType.AllDirectories);
var modManifests = from manifest in manifests var modManifests = from manifest in manifests
@ -439,20 +454,5 @@ namespace HashCalculator.GUI
{ {
return VirtualFileSystem.GetFileName(path).StartsWith(what, StringComparison.OrdinalIgnoreCase); return VirtualFileSystem.GetFileName(path).StartsWith(what, StringComparison.OrdinalIgnoreCase);
} }
private static async Task ExceptionWrapepr(Func<Task> action, string errorTitle, string preErrorMessage)
{
try
{
await action().ConfigureAwait(true);
}
catch (Exception exception)
{
CopyableBox.ShowDialog(errorTitle, _ =>
{
return Task.FromResult(preErrorMessage + exception);
});
}
}
} }
} }

View File

@ -1,43 +1,39 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; 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 System.Windows.Threading;
using TechnologyAssembler.Core.Extensions;
namespace HashCalculator.GUI namespace HashCalculator.GUI
{ {
public class ShowCopyableBoxEventArgs : EventArgs
{
public string Title { get; }
public Func<CancellationToken, Task<string>> GetContent { get; }
public Task Completion { get; set; }
public ShowCopyableBoxEventArgs(string title, Func<CancellationToken, Task<string>> getContent)
{
Title = title;
GetContent = getContent;
Completion = Task.CompletedTask;
}
}
/// <summary> /// <summary>
/// CopyableBox.xaml 的交互逻辑 /// CopyableBox.xaml 的交互逻辑
/// </summary> /// </summary>
[SuppressMessage("Microsoft.Performance", "CA1812")]
internal partial class CopyableBox : Window, IDisposable internal partial class CopyableBox : Window, IDisposable
{ {
private CopyableBoxViewModel ViewModel => (CopyableBoxViewModel)DataContext; private CopyableBoxViewModel ViewModel => (CopyableBoxViewModel)DataContext;
public static void ShowDialog(string title, Func<CancellationToken, Task<string>> action) public CopyableBox(Window owner, string title, Func<CancellationToken, Task<string>> action)
{
using var box = new CopyableBox();
box.ViewModel.Initialize(title, action, box.Dispatcher);
box.Owner = App.Current.MainWindow;
box.ShowDialog();
}
private CopyableBox()
{ {
InitializeComponent(); InitializeComponent();
Owner = owner;
ViewModel.Initialize(title, action, Dispatcher);
} }
public void Dispose() public void Dispose()
@ -45,7 +41,7 @@ namespace HashCalculator.GUI
ViewModel.Dispose(); ViewModel.Dispose();
} }
private void ClosingHandler(object sender, CancelEventArgs e) private async void ClosingHandler(object sender, CancelEventArgs e)
{ {
if (ViewModel.ReadyToClose) if (ViewModel.ReadyToClose)
{ {
@ -53,19 +49,18 @@ namespace HashCalculator.GUI
} }
e.Cancel = true; e.Cancel = true;
await Dispatcher.Yield();
if (ViewModel.CloseCommand.CanExecuteValue) if (ViewModel.CloseCommand.CanExecuteValue)
{ {
ViewModel.CloseCommand.Execute(this); ViewModel.CloseCommand.Execute(this);
} }
return; return;
} }
} }
[SuppressMessage("Microsoft.Performance", "CA1812")]
internal class CopyableBoxViewModel : NotifyPropertyChanged, IDisposable internal class CopyableBoxViewModel : NotifyPropertyChanged, IDisposable
{ {
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private readonly CancellationTokenSource _cancellationTokenSource = new();
private Task? _task; private Task? _task;
private string _title = "我居然没有名字qwq"; private string _title = "我居然没有名字qwq";
@ -113,7 +108,7 @@ namespace HashCalculator.GUI
try try
{ {
Cancel(); Cancel();
await _task.ConfigureAwait(true); await _task;
} }
catch (OperationCanceledException) { } catch (OperationCanceledException) { }
} }
@ -147,14 +142,14 @@ namespace HashCalculator.GUI
Text = $"{InitialMessage}\r\n目前耗时{timer.TimeSinceCreation}稍微再等一下吧233"; Text = $"{InitialMessage}\r\n目前耗时{timer.TimeSinceCreation}稍微再等一下吧233";
}, dispatcher, TimeSpan.FromMilliseconds(200), TimeSpan.FromSeconds(1)); }, dispatcher, TimeSpan.FromMilliseconds(200), TimeSpan.FromSeconds(1));
return await action(token).ConfigureAwait(false); return await action(token);
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
return "操作已被取消"; return "操作已被取消";
} }
} }
Text = await dispatcher.Invoke(Action).ConfigureAwait(true); Text = await dispatcher.Invoke(Action);
} }
private void Cancel() private void Cancel()

View File

@ -24,10 +24,22 @@ namespace HashCalculator.GUI
{ {
ViewModel.NotifyCsfChange(); ViewModel.NotifyCsfChange();
}); });
ViewModel.ShowCopyableBox += ViewModel_ShowCopyableBox;
ViewModel.OpenFileDialog += ViewModel_OpenFileDialog; ViewModel.OpenFileDialog += ViewModel_OpenFileDialog;
ViewModel.ClearTracer += ViewModel_ClearTracer; ViewModel.ClearTracer += ViewModel_ClearTracer;
} }
private void ViewModel_ShowCopyableBox(object? sender, ShowCopyableBoxEventArgs e)
{
var title = e.Title;
var getContent = e.GetContent;
e.Completion = Dispatcher.InvokeAsync(() =>
{
using var box = new CopyableBox(this, title, getContent);
box.ShowDialog();
}).Task;
}
private void ViewModel_OpenFileDialog(object? sender, OpenFileDialogEventArgs e) private void ViewModel_OpenFileDialog(object? sender, OpenFileDialogEventArgs e)
{ {
var sdkRoot = new OpenFileDialog var sdkRoot = new OpenFileDialog

View File

@ -6,6 +6,7 @@ using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using TechnologyAssembler.Core.IO; using TechnologyAssembler.Core.IO;
@ -62,6 +63,7 @@ namespace HashCalculator.GUI
{ {
private static readonly Random _random = new(); private static readonly Random _random = new();
public event EventHandler? ClearTracer; public event EventHandler? ClearTracer;
public event EventHandler<ShowCopyableBoxEventArgs>? ShowCopyableBox;
public event EventHandler<OpenFileDialogEventArgs>? OpenFileDialog; public event EventHandler<OpenFileDialogEventArgs>? OpenFileDialog;
public MainInputViewModel MainInput { get; } public MainInputViewModel MainInput { get; }
public BigInputViewModel BigEntryInput { get; } public BigInputViewModel BigEntryInput { get; }
@ -157,7 +159,7 @@ namespace HashCalculator.GUI
var fileName = await controller.RequestOpenFile(string.Empty, ("*.csf;*.big", "CSF / BIG 文件")); var fileName = await controller.RequestOpenFile(string.Empty, ("*.csf;*.big", "CSF / BIG 文件"));
if (fileName is not null) if (fileName is not null)
{ {
await Controller.LoadCsf(fileName).ConfigureAwait(true); await controller.LoadCsf(fileName).ConfigureAwait(true);
} }
} }
finally finally
@ -177,6 +179,13 @@ namespace HashCalculator.GUI
}); });
} }
public Task RequestCopyableBox(string title, Func<CancellationToken, Task<string>> getContent)
{
var data = new ShowCopyableBoxEventArgs(title, getContent);
ShowCopyableBox?.Invoke(this, data);
return data.Completion;
}
public Task<string?> RequestOpenFile(string title, IEnumerable<(string Extension, string? Description)> filters) public Task<string?> RequestOpenFile(string title, IEnumerable<(string Extension, string? Description)> filters)
{ {
var data = new OpenFileDialogEventArgs(title, filters); var data = new OpenFileDialogEventArgs(title, filters);
@ -474,10 +483,10 @@ namespace HashCalculator.GUI
} }
catch (Exception exception) catch (Exception exception)
{ {
CopyableBox.ShowDialog("SAGE FastHash 计算器的错误", _ => await viewModel.RequestCopyableBox("SAGE FastHash 计算器的错误", _ =>
{ {
return Task.FromResult($"在加载 manifest 时发生错误:{exception}"); return Task.FromResult($"在加载 manifest 时发生错误:{exception}");
}); });
} }
finally finally
{ {