HashCalculator.GUI/Command.cs
2021-09-06 23:14:21 +02:00

128 lines
3.3 KiB
C#

using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace HashCalculator.GUI
{
internal class Command<T> : ICommand
{
private readonly Func<T, Task> _action;
private readonly Action<Exception> _onAsyncException;
private bool _canExecute = true;
public bool CanExecuteValue
{
get => _canExecute;
set
{
_canExecute = value;
CanExecuteChanged?.Invoke(this, new EventArgs());
}
}
public event EventHandler? CanExecuteChanged;
public Command(Func<T, Task> action, Action<Exception>? onAsyncException = null)
{
_action = action;
_onAsyncException = onAsyncException ?? (exception =>
{
MessageBox.Show($"Unhandled async exception in {nameof(Command<T>)}: {exception}");
Application.Current.Shutdown(1);
});
}
public bool CanExecute(object? parameter)
{
return _canExecute;
}
public void Execute(object? parameter)
{
if (!_canExecute)
{
return;
}
if (!(parameter is T typed))
{
throw new ArgumentException($"{nameof(parameter)} wrong type");
}
ExecuteTaskInternal(ExecuteTask(typed));
}
public Task ExecuteTask(T parameter) => _action(parameter);
private async void ExecuteTaskInternal(Task task)
{
try
{
await task.ConfigureAwait(true);
}
catch (Exception exception)
{
_onAsyncException(exception);
}
}
}
internal class Command : ICommand
{
private readonly Func<Task> _action;
private readonly Action<Exception> _onAsyncException;
private bool _canExecute = true;
public bool CanExecuteValue
{
get => _canExecute;
set
{
_canExecute = value;
CanExecuteChanged?.Invoke(this, new EventArgs());
}
}
public event EventHandler? CanExecuteChanged;
public Command(Func<Task> action, Action<Exception>? onAsyncException = null)
{
_action = action;
_onAsyncException = onAsyncException ?? (exception =>
{
MessageBox.Show($"Unhandled async exception in {nameof(Command)}: {exception}");
Application.Current.Shutdown(1);
});
}
public bool CanExecute(object? parameter)
{
return _canExecute;
}
public void Execute(object? parameter)
{
if (!_canExecute)
{
return;
}
ExecuteTaskInternal(ExecuteTask());
}
public Task ExecuteTask() => _action();
private async void ExecuteTaskInternal(Task task)
{
try
{
await task.ConfigureAwait(true);
}
catch (Exception exception)
{
_onAsyncException(exception);
}
}
}
}