试图修弹窗崩溃

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:
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;
return;
case InputEntryType.BigFile:
@ -62,7 +62,7 @@ namespace HashCalculator.GUI
catch (Exception error)
{
ViewModel.StatusText = "失败…";
CopyableBox.ShowDialog("SAGE FastHash 计算器 - 失败!", _ =>
await ViewModel.RequestCopyableBox("SAGE FastHash 计算器 - 失败!", _ =>
{
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 () =>
{
@ -417,7 +417,22 @@ namespace HashCalculator.GUI
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 modManifests = from manifest in manifests
@ -439,20 +454,5 @@ namespace HashCalculator.GUI
{
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.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
{
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>
/// CopyableBox.xaml 的交互逻辑
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1812")]
internal partial class CopyableBox : Window, IDisposable
{
private CopyableBoxViewModel ViewModel => (CopyableBoxViewModel)DataContext;
public static void ShowDialog(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()
public CopyableBox(Window owner, string title, Func<CancellationToken, Task<string>> action)
{
InitializeComponent();
Owner = owner;
ViewModel.Initialize(title, action, Dispatcher);
}
public void Dispose()
@ -45,7 +41,7 @@ namespace HashCalculator.GUI
ViewModel.Dispose();
}
private void ClosingHandler(object sender, CancelEventArgs e)
private async void ClosingHandler(object sender, CancelEventArgs e)
{
if (ViewModel.ReadyToClose)
{
@ -53,19 +49,18 @@ namespace HashCalculator.GUI
}
e.Cancel = true;
await Dispatcher.Yield();
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 readonly CancellationTokenSource _cancellationTokenSource = new();
private Task? _task;
private string _title = "我居然没有名字qwq";
@ -113,7 +108,7 @@ namespace HashCalculator.GUI
try
{
Cancel();
await _task.ConfigureAwait(true);
await _task;
}
catch (OperationCanceledException) { }
}
@ -147,14 +142,14 @@ namespace HashCalculator.GUI
Text = $"{InitialMessage}\r\n目前耗时{timer.TimeSinceCreation}稍微再等一下吧233";
}, dispatcher, TimeSpan.FromMilliseconds(200), TimeSpan.FromSeconds(1));
return await action(token).ConfigureAwait(false);
return await action(token);
}
catch (OperationCanceledException)
{
return "操作已被取消";
}
}
Text = await dispatcher.Invoke(Action).ConfigureAwait(true);
Text = await dispatcher.Invoke(Action);
}
private void Cancel()

View File

@ -24,10 +24,22 @@ namespace HashCalculator.GUI
{
ViewModel.NotifyCsfChange();
});
ViewModel.ShowCopyableBox += ViewModel_ShowCopyableBox;
ViewModel.OpenFileDialog += ViewModel_OpenFileDialog;
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)
{
var sdkRoot = new OpenFileDialog

View File

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