55 lines
1.3 KiB
C#
55 lines
1.3 KiB
C#
using System.Windows.Input;
|
|
|
|
namespace Zcbot.WindowsNode;
|
|
|
|
internal sealed class AsyncCommand : ObservableObject, ICommand
|
|
{
|
|
private readonly Func<Task> execute;
|
|
private readonly Func<bool>? canExecute;
|
|
private bool isRunning;
|
|
|
|
internal AsyncCommand(Func<Task> execute, Func<bool>? canExecute = null)
|
|
{
|
|
this.execute = execute;
|
|
this.canExecute = canExecute;
|
|
}
|
|
|
|
public event EventHandler? CanExecuteChanged;
|
|
|
|
internal event Action<Exception>? Failed;
|
|
|
|
internal bool IsRunning
|
|
{
|
|
get => isRunning;
|
|
private set
|
|
{
|
|
if (SetProperty(ref isRunning, value))
|
|
{
|
|
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool CanExecute(object? parameter) => !IsRunning && (canExecute?.Invoke() ?? true);
|
|
|
|
public async void Execute(object? parameter)
|
|
{
|
|
if (!CanExecute(parameter)) return;
|
|
IsRunning = true;
|
|
try
|
|
{
|
|
await execute();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Failed?.Invoke(exception);
|
|
}
|
|
finally
|
|
{
|
|
IsRunning = false;
|
|
}
|
|
}
|
|
|
|
internal void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
|
}
|