Files
XLIMS/XLIMS.MVVM/Base/AsyncRelayCommand.cs
Курнат Андрей f0e11d6379 first edit
2026-01-31 16:11:36 +03:00

112 lines
3.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Input;
namespace XLIMS.MVVM.Base
{
/// <summary>
/// Асинхронная команда без параметра.
/// </summary>
public class AsyncRelayCommand : ICommand
{
private readonly Func<Task> _execute;
private readonly Func<bool>? _canExecute;
private bool _isExecuting;
public AsyncRelayCommand(Func<Task> execute, Func<bool>? 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<object?, Task> execute, Func<object?, bool>? canExecute = null)
{
return new AsyncRelayCommand(() => execute(null), canExecute == null ? null : () => canExecute(null));
}
}
/// <summary>
/// Асинхронная команда с параметром (типизированная).
/// </summary>
public class AsyncRelayCommand<T> : ICommand
{
private readonly Func<T?, Task> _execute;
private readonly Predicate<T?>? _canExecute;
private bool _isExecuting;
public AsyncRelayCommand(Func<T?, Task> execute, Predicate<T?>? 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; }
}
}
}