127 lines
3.2 KiB
C#
127 lines
3.2 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
|
|
namespace JD.Guinness.WPF.Module
|
|
{
|
|
public sealed class AsyncDelegateCommand : ICommand
|
|
{
|
|
#region Fields
|
|
|
|
private readonly Func<Task> _executeAsync;
|
|
private readonly Func<bool> _canExecute;
|
|
|
|
private volatile bool _isExecuting;
|
|
|
|
#endregion
|
|
|
|
#region Initialisation
|
|
|
|
public AsyncDelegateCommand(Func<Task> executeAsync, Func<bool> canExecute)
|
|
{
|
|
_executeAsync = executeAsync ?? throw new ArgumentNullException(nameof(executeAsync));
|
|
_canExecute = canExecute;
|
|
}
|
|
|
|
public AsyncDelegateCommand(Func<Task> executeAsync)
|
|
: this(executeAsync, null)
|
|
{ }
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
public bool CanExecute() => !_isExecuting && (_canExecute?.Invoke() ?? true);
|
|
|
|
public async Task ExecuteAsync()
|
|
{
|
|
_isExecuting = true;
|
|
|
|
await _executeAsync().ConfigureAwait(true);
|
|
|
|
_isExecuting = false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ICommand
|
|
|
|
event EventHandler ICommand.CanExecuteChanged
|
|
{
|
|
add { CommandManager.RequerySuggested += value; }
|
|
remove { CommandManager.RequerySuggested -= value; }
|
|
}
|
|
|
|
bool ICommand.CanExecute(object parameter) => CanExecute();
|
|
|
|
async void ICommand.Execute(object parameter) => await ExecuteAsync().ConfigureAwait(true);
|
|
|
|
#endregion
|
|
}
|
|
|
|
public sealed class AsyncDelegateCommand<T> : ICommand
|
|
{
|
|
#region Fields
|
|
|
|
private readonly Func<T, Task> _executeAsync;
|
|
private readonly Predicate<T> _canExecute;
|
|
private readonly bool _isClass;
|
|
|
|
private volatile bool _isExecuting;
|
|
|
|
#endregion
|
|
|
|
#region Initialisation
|
|
|
|
public AsyncDelegateCommand(Func<T, Task> executeAsync, Predicate<T> canExecute)
|
|
{
|
|
_executeAsync = executeAsync ?? throw new ArgumentNullException(nameof(executeAsync));
|
|
_canExecute = canExecute;
|
|
_isClass = typeof(T).IsClass;
|
|
}
|
|
|
|
public AsyncDelegateCommand(Func<T, Task> executeAsync)
|
|
: this(executeAsync, null)
|
|
{ }
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
public bool CanExecute(T parameter) => !_isExecuting && (_canExecute?.Invoke(parameter) ?? true);
|
|
|
|
public async Task ExecuteAsync(T parameter)
|
|
{
|
|
_isExecuting = true;
|
|
|
|
await _executeAsync(parameter).ConfigureAwait(true);
|
|
|
|
_isExecuting = false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ICommand
|
|
|
|
event EventHandler ICommand.CanExecuteChanged
|
|
{
|
|
add { CommandManager.RequerySuggested += value; }
|
|
remove { CommandManager.RequerySuggested -= value; }
|
|
}
|
|
|
|
bool ICommand.CanExecute(object parameter)
|
|
{
|
|
if (!(parameter is T)
|
|
|| (parameter == null && !_isClass))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return CanExecute((T)parameter);
|
|
}
|
|
|
|
async void ICommand.Execute(object parameter) => await ExecuteAsync((T)parameter).ConfigureAwait(true);
|
|
|
|
#endregion
|
|
}
|
|
}
|