AsyncRelayCommand и AsyncRelayCommand<T>
ICommand
AsyncRelayCommand<T>
РеализацииAsyncRelayCommand
, расширяющие функциональные возможности, предоставляемые RelayCommand
с поддержкой асинхронных операций.
API платформы:
AsyncRelayCommand
,AsyncRelayCommand<T>
,RelayCommand
IAsyncRelayCommand
IAsyncRelayCommand<T>
Принцип работы
AsyncRelayCommand
и AsyncRelayCommand<T>
имеют следующие основные функции:
- Они расширяют функциональные возможности синхронных команд, включенных в библиотеку, с поддержкой
Task
возвращающих делегатов. - Они могут упаковать асинхронные функции с дополнительным
CancellationToken
параметром для поддержки отмены, а также предоставлятьCanBeCanceled
свойства иIsCancellationRequested
свойства, а такжеCancel
метод. - Они предоставляют
ExecutionTask
свойство, которое можно использовать для мониторинга хода выполнения ожидающей операции, иIsRunning
можно использовать для проверки завершения операции. Это особенно полезно для привязки команды к элементам пользовательского интерфейса, таким как индикаторы загрузки. - Они реализуют
IAsyncRelayCommand
интерфейсы иIAsyncRelayCommand<T>
интерфейсы, что означает, что viewmodel может легко предоставлять команды с помощью этих команд для уменьшения жесткой связи между типами. Например, это упрощает замену команды пользовательской реализацией, предоставляющей одну и ту же общедоступную область API при необходимости.
Работа с асинхронными командами
Предположим сценарий, аналогичный описанному в RelayCommand
примере, но команда, выполняющая асинхронную операцию:
public class MyViewModel : ObservableObject
{
public MyViewModel()
{
DownloadTextCommand = new AsyncRelayCommand(DownloadText);
}
public IAsyncRelayCommand DownloadTextCommand { get; }
private Task<string> DownloadText()
{
return WebService.LoadMyTextAsync();
}
}
С соответствующим кодом пользовательского интерфейса:
<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>
После нажатия Button
кнопки вызывается команда и ExecutionTask
обновляется. После завершения операции свойство вызывает уведомление, которое отражается в пользовательском интерфейсе. В этом случае отображаются состояние задачи и текущий результат задачи. Обратите внимание, что для отображения результата задачи необходимо использовать TaskExtensions.GetResultOrDefault
метод . Это обеспечивает доступ к результату задачи, которая еще не завершена, не блокируя поток (и, возможно, вызывая взаимоблокировку).
Примеры
- Ознакомьтесь с примером приложения (для нескольких платформ пользовательского интерфейса), чтобы просмотреть набор средств MVVM в действии.
- Дополнительные примеры можно найти в модульных тестах.
MVVM Toolkit