AsyncRelayCommand et AsyncRelayCommand<T>
AsyncRelayCommand
et AsyncRelayCommand<T>
sont des implémentations ICommand
qui étendent les fonctionnalités offertes par RelayCommand
, avec prise en charge des opérations asynchrones.
API de plateforme :
AsyncRelayCommand
,AsyncRelayCommand<T>
,RelayCommand
,IAsyncRelayCommand
,IAsyncRelayCommand<T>
Fonctionnement
Les implémentations AsyncRelayCommand
et AsyncRelayCommand<T>
incluent les principales fonctionnalités suivantes :
- Elles étendent les fonctionnalités des commandes synchrones incluses dans la bibliothèque, avec prise en charge des délégués retournant
Task
. - Elles peuvent encapsuler des fonctions asynchrones avec un paramètre
CancellationToken
supplémentaire pour prendre en charge l’annulation, et exposent les propriétésCanBeCanceled
etIsCancellationRequested
, ainsi qu’une méthodeCancel
. - Elles exposent une propriété
ExecutionTask
qui peut être utilisée pour surveiller la progression d’une opération en attente, et une propriétéIsRunning
qui peut être utilisée pour vérifier la fin d’une opération. C’est particulièrement utile pour lier une commande à des éléments d’interface utilisateur tels que des indicateurs de chargement. - Elles implémentent les interfaces
IAsyncRelayCommand
etIAsyncRelayCommand<T>
, ce qui signifie que viewmodel peut facilement exposer des commandes à l’aide de celles-ci pour réduire le couplage étroit entre les types. Par exemple, elles facilitent le remplacement d’une commande par une implémentation personnalisée exposant la même surface d’API publique, si nécessaire.
Utilisation de commandes asynchrones
Imaginons un scénario similaire à celui décrit dans l’exemple RelayCommand
, mais avec une commande exécutant une opération asynchrone :
public class MyViewModel : ObservableObject
{
public MyViewModel()
{
DownloadTextCommand = new AsyncRelayCommand(DownloadText);
}
public IAsyncRelayCommand DownloadTextCommand { get; }
private Task<string> DownloadText()
{
return WebService.LoadMyTextAsync();
}
}
Avec le code d’interface utilisateur associé :
<Page
x:Class="MyApp.Views.MyPage"
xmlns:viewModels="using:MyApp.ViewModels"
xmlns:converters="using:Microsoft.Toolkit.Uwp.UI.Converters">
<Page.DataContext>
<viewModels:MyViewModel x:Name="ViewModel"/>
</Page.DataContext>
<Page.Resources>
<converters:TaskResultConverter x:Key="TaskResultConverter"/>
</Page.Resources>
<StackPanel Spacing="8" xml:space="default">
<TextBlock>
<Run Text="Task status:"/>
<Run Text="{x:Bind ViewModel.DownloadTextCommand.ExecutionTask.Status, Mode=OneWay}"/>
<LineBreak/>
<Run Text="Result:"/>
<Run Text="{x:Bind ViewModel.DownloadTextCommand.ExecutionTask, Converter={StaticResource TaskResultConverter}, Mode=OneWay}"/>
</TextBlock>
<Button
Content="Click me!"
Command="{x:Bind ViewModel.DownloadTextCommand}"/>
<ProgressRing
HorizontalAlignment="Left"
IsActive="{x:Bind ViewModel.DownloadTextCommand.IsRunning, Mode=OneWay}"/>
</StackPanel>
</Page>
Lorsque vous cliquez sur le bouton Button
, la commande est appelée et la tâche ExecutionTask
est mise à jour. Une fois l’opération terminée, la propriété déclenche une notification qui s’affiche dans l’interface utilisateur. Dans ce cas, l’état de la tâche et le résultat actuel de la tâche sont affichés. Notez que pour afficher le résultat de la tâche, il est nécessaire d’utiliser la méthode TaskExtensions.GetResultOrDefault
qui permet d’accéder au résultat d’une tâche non encore terminée sans bloquer le thread (et éventuellement provoquer un interblocage).
Exemples
- Consultez l’exemple d’application (pour plusieurs infrastructures d’interface utilisateur) afin de voir le Kit d’outils Modèle-vue-vue modèle (MVVM) en action.
- Vous trouverez également d’autres exemples dans les tests unitaires.