using System; using System.Diagnostics; using System.Threading.Tasks; using System.Windows.Input; namespace XLIMS.MVVM.Base { /// /// Асинхронная команда без параметра. /// public class AsyncRelayCommand : ICommand { private readonly Func _execute; private readonly Func? _canExecute; private bool _isExecuting; public AsyncRelayCommand(Func execute, Func? canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object? parameter) { if (_isExecuting) return false; return _canExecute == null || _canExecute(); } public async void Execute(object? parameter) { if (!CanExecute(parameter)) return; try { _isExecuting = true; CommandManager.InvalidateRequerySuggested(); await _execute(); } finally { _isExecuting = false; CommandManager.InvalidateRequerySuggested(); } } public event EventHandler? CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } // Удобный статический метод для создания из метода с параметром (если вдруг понадобится) public static AsyncRelayCommand FromAsync(Func execute, Func? canExecute = null) { return new AsyncRelayCommand(() => execute(null), canExecute == null ? null : () => canExecute(null)); } } /// /// Асинхронная команда с параметром (типизированная). /// public class AsyncRelayCommand : ICommand { private readonly Func _execute; private readonly Predicate? _canExecute; private bool _isExecuting; public AsyncRelayCommand(Func execute, Predicate? canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object? parameter) { if (_isExecuting) return false; if (_canExecute == null) return true; // Если параметр неправильного типа — считаем, что нельзя выполнить return parameter is T typedParam && _canExecute(typedParam); } public async void Execute(object? parameter) { if (!CanExecute(parameter)) return; T? typedParam = parameter is T p ? p : default; try { _isExecuting = true; CommandManager.InvalidateRequerySuggested(); await _execute(typedParam); } finally { _isExecuting = false; CommandManager.InvalidateRequerySuggested(); } } public event EventHandler? CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } } }