Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
AsyncRelayCommand и AsyncRelayCommand<T> — это реализации ICommand, которые расширяют функциональные возможности, предоставляемые RelayCommand, и поддерживают асинхронные операции.
API платформы:
AsyncRelayCommand,AsyncRelayCommand<T>,RelayCommandIAsyncRelayCommandIAsyncRelayCommand<T>
Принцип работы
AsyncRelayCommand и AsyncRelayCommand<T> имеют следующие основные функции:
- Они расширяют функциональность синхронных команд, включённых в библиотеку, и добавляют поддержку делегатов, возвращающих
Task. - Они могут оборачивать асинхронные функции, добавляя дополнительный параметр
CancellationTokenдля поддержки отмены операции, а также предоставляют свойстваCanBeCanceledиIsCancellationRequested, а также методCancel. - Они предоставляют свойство
ExecutionTask, которое можно использовать для отслеживания хода выполнения незавершённой операции, и элементIsRunning, который можно использовать, чтобы определить, когда операция завершится. Это особенно полезно для привязки команды к элементам пользовательского интерфейса, таким как индикаторы загрузки. - Они реализуют интерфейсы
IAsyncRelayCommandиIAsyncRelayCommand<T>, что означает, что модель представления может легко предоставлять команды с их помощью, уменьшая жесткую связанность между типами. Например, это упрощает замену команды пользовательской реализацией, предоставляющей одну и ту же общедоступную область 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