zcbot/windows-node/Zcbot.WindowsNode/Presentation/Infrastructure/AsyncCommand.cs

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);
}