Skip to content

Commit 3c71d4b

Browse files
committed
Notify CanExecute when invoking an async command
1 parent 5dcc52b commit 3c71d4b

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

CommunityToolkit.Mvvm/Input/AsyncRelayCommand.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,21 +265,33 @@ public Task ExecuteAsync(object? parameter)
265265
{
266266
if (CanExecute(parameter))
267267
{
268-
// Non cancelable command delegate
268+
Task executionTask;
269+
269270
if (this.execute is not null)
270271
{
271-
return ExecutionTask = this.execute();
272+
// Non cancelable command delegate
273+
executionTask = ExecutionTask = this.execute();
272274
}
275+
else
276+
{
277+
// Cancel the previous operation, if one is pending
278+
this.cancellationTokenSource?.Cancel();
279+
280+
CancellationTokenSource cancellationTokenSource = this.cancellationTokenSource = new();
273281

274-
// Cancel the previous operation, if one is pending
275-
this.cancellationTokenSource?.Cancel();
282+
PropertyChanged?.Invoke(this, IsCancellationRequestedChangedEventArgs);
276283

277-
CancellationTokenSource cancellationTokenSource = this.cancellationTokenSource = new();
284+
// Invoke the cancelable command delegate with a new linked token
285+
executionTask = ExecutionTask = this.cancelableExecute!(cancellationTokenSource.Token);
286+
}
278287

279-
PropertyChanged?.Invoke(this, IsCancellationRequestedChangedEventArgs);
288+
// If concurrent executions are disabled, notify the can execute change as well
289+
if (!this.allowConcurrentExecutions)
290+
{
291+
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
292+
}
280293

281-
// Invoke the cancelable command delegate with a new linked token
282-
return ExecutionTask = this.cancelableExecute!(cancellationTokenSource.Token);
294+
return executionTask;
283295
}
284296

285297
return Task.CompletedTask;

CommunityToolkit.Mvvm/Input/AsyncRelayCommand{T}.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -269,21 +269,34 @@ public Task ExecuteAsync(T? parameter)
269269
{
270270
if (CanExecute(parameter))
271271
{
272-
// Non cancelable command delegate
272+
Task executionTask;
273+
274+
273275
if (this.execute is not null)
274276
{
275-
return ExecutionTask = this.execute(parameter);
277+
// Non cancelable command delegate
278+
executionTask = ExecutionTask = this.execute(parameter);
276279
}
280+
else
281+
{
282+
// Cancel the previous operation, if one is pending
283+
this.cancellationTokenSource?.Cancel();
284+
285+
CancellationTokenSource cancellationTokenSource = this.cancellationTokenSource = new();
277286

278-
// Cancel the previous operation, if one is pending
279-
this.cancellationTokenSource?.Cancel();
287+
PropertyChanged?.Invoke(this, AsyncRelayCommand.IsCancellationRequestedChangedEventArgs);
280288

281-
CancellationTokenSource cancellationTokenSource = this.cancellationTokenSource = new();
289+
// Invoke the cancelable command delegate with a new linked token
290+
executionTask = ExecutionTask = this.cancelableExecute!(parameter, cancellationTokenSource.Token);
291+
}
282292

283-
PropertyChanged?.Invoke(this, AsyncRelayCommand.IsCancellationRequestedChangedEventArgs);
293+
// If concurrent executions are disabled, notify the can execute change as well
294+
if (!this.allowConcurrentExecutions)
295+
{
296+
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
297+
}
284298

285-
// Invoke the cancelable command delegate with a new linked token
286-
return ExecutionTask = this.cancelableExecute!(parameter, cancellationTokenSource.Token);
299+
return executionTask;
287300
}
288301

289302
return Task.CompletedTask;

0 commit comments

Comments
 (0)