AsyncRelayCommand と AsyncRelayCommand<T>
AsyncRelayCommand
と AsyncRelayCommand<T>
は、RelayCommand
によって提供される機能を非同期操作のサポートで拡張する、ICommand
の実装です。
プラットフォーム API:
AsyncRelayCommand
、AsyncRelayCommand<T>
、RelayCommand
、IAsyncRelayCommand
、IAsyncRelayCommand<T>
そのしくみ
AsyncRelayCommand
と AsyncRelayCommand<T>
の主な機能は次のとおりです。
- ライブラリに含まれる同期コマンドの機能を、
Task
を返すデリゲートのサポートで拡張します。 - 取り消しをサポートするために追加された
CancellationToken
パラメーターで非同期関数をラップでき、CanBeCanceled
とIsCancellationRequested
プロパティおよびCancel
メソッドを公開します。 - 保留中の操作の進行状況を監視するために使用できる
ExecutionTask
プロパティと、操作が完了したタイミングを調べるために使用できるIsRunning
を公開します。 これは、読み込みインジケーターなどの UI 要素にコマンドをバインドするのに特に便利です。 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();
}
}
関連する UI コードは次のとおりです。
<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
が更新されます。 操作が完了すると、プロパティは UI に反映される通知を生成します。 この場合、タスクの状態とタスクの現在の結果の両方が表示されます。 タスクの結果を表示するには、TaskExtensions.GetResultOrDefault
メソッドを使う必要があることに注意してください。これにより、スレッドをブロックすることなく (デッドロックの原因になる可能性があります)、まだ完了していないタスクの結果にアクセスできます。
例
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
MVVM Toolkit