Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
2度押し防止コマンド試作
using Reactive.Bindings.Notifiers;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Reactive.Bindings
{
public class BusyNotifierCommand : BusyNotifierCommand<object>
{
public BusyNotifierCommand(Func<Task> execute)
:base(async _ => await execute(), null)
{
}
public BusyNotifierCommand(Func<Task> execute, Func<bool> canExecute)
:base(_ => execute(), _ => canExecute())
{
}
}
public class BusyNotifierCommand<T> : ICommand
{
private Func<T, Task> execute;
private Func<T, bool> canExecute;
private bool previousCanExecute;
public BusyNotifierCommand(Func<T, Task> execute)
{
this.execute = execute;
}
public BusyNotifierCommand(Func<T, Task> execute, Func<T, bool> canExecute)
{
this.execute = execute;
this.canExecute = canExecute;
}
private BusyNotifier BusyNotifier { get; } = new BusyNotifier();
public bool IsBusy => BusyNotifier.IsBusy;
public event EventHandler CanExecuteChanged;
public bool CanExecute(T parameter)
{
if (canExecute != null)
{
if (canExecute(parameter) == false)
{
if (previousCanExecute != false)
{
previousCanExecute = false;
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
return false;
}
}
var result = IsBusy == false;
if (previousCanExecute != result)
{
previousCanExecute = result;
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
return result;
}
bool ICommand.CanExecute(object parameter)
{
return CanExecute((T)parameter);
}
public async void Execute(T parameter)
{
if (IsBusy) return;
using (BusyNotifier.ProcessStart())
{
await execute(parameter);
}
}
void ICommand.Execute(object parameter)
{
Execute((T)parameter);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment