2using System.ComponentModel;
3using System.Threading.Tasks;
4using CommunityToolkit.Mvvm.Input;
9 public enum ObservableTaskCommandOptions
12 AllowConcurrentRestart = 1 << 0,
17 private readonly Func<TaskContext<TProgress>, Task> taskFactory;
18 private readonly Func<bool>? canExecute;
19 private readonly ObservableTaskCommandOptions options;
26 :
this(taskFactory,
null, ObservableTaskCommandOptions.None)
33 Func<bool>? canExecute,
34 ObservableTaskCommandOptions options = ObservableTaskCommandOptions.None)
36 this.taskFactory = taskFactory ??
throw new ArgumentNullException(nameof(taskFactory));
37 this.canExecute = canExecute;
38 this.options = options;
41 this.Notifier.PropertyChanged += (s, e) => this.PropertyChanged?.Invoke(
this, e);
52 this.NotifyCanExecuteChanged();
55 this.Notifier.
Load(ctx => this.taskFactory(ctx),
this);
60 await Task.ContinueWith(
61 _ => this.NotifyCanExecuteChanged(),
62 TaskScheduler.FromCurrentSynchronizationContext());
63 this.NotifyCanExecuteChanged();
77 bool BaseCanExecute = this.canExecute?.Invoke() ??
true;
82 if ((this.options & ObservableTaskCommandOptions.AllowConcurrentRestart) == 0)
84 if (this.Notifier.IsRunning)
90 public event EventHandler? CanExecuteChanged;
91 public void NotifyCanExecuteChanged() => this.CanExecuteChanged?.Invoke(
this, EventArgs.Empty);
98 public event PropertyChangedEventHandler? PropertyChanged;
103 public void Cancel() => this.Notifier.Cancel();
114 this.Notifier.CancellationTokenSource is not
null &&
115 this.Notifier.CurrentTask is not
null &&
116 !this.Notifier.CurrentTask.IsCompleted;
126 public bool IsRunning => this.Notifier.CurrentTask is { IsCompleted:
false };
bool IsCancellationRequested
Indicates whether cancellation has been requested.
bool IsRunning
Indicates whether the command is currently running.
void Cancel()
Cancels the running task.
bool CanExecute(object? parameter)
Checks whether the command can execute.
async Task ExecuteAsync()
Executes the task by starting it through the notifier.
Task ExecuteAsync(object? parameter)
IAsyncRelayCommand overload.
void Execute(object? parameter)
ICommand implementation.
bool CanBeCanceled
Indicates whether the command can be canceled.
Task? ExecutionTask
Exposes the currently executing task.
Provides a data-binding friendly mechanism to manage and report the status of asynchronous operations...
Task? CurrentTask
The current task being processed.
void Load(Func< TaskContext< TProgress >, Task > task, params IRelayCommand[] notifyCommands)
Loads (configures) and immediately starts the task (back-compat convenience).
class TaskContext< TProgress >(bool IsRefreshing, CancellationToken CancellationToken, IProgress< TProgress > Progress)
Represents the context for an asynchronous task execution.