using System.Windows.Input; namespace Zcbot.WindowsNode; internal sealed class AsyncCommand : ObservableObject, ICommand { private readonly Func execute; private readonly Func? canExecute; private bool isRunning; internal AsyncCommand(Func execute, Func? canExecute = null) { this.execute = execute; this.canExecute = canExecute; } public event EventHandler? CanExecuteChanged; internal event Action? 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); }