来自ReactiveAsyncCommand的UI访问

时间:2013-04-13 07:17:25

标签: wpf ui-thread reactiveui

我想注册一个打开文件并处理它的异步命令。

OpenFileCommand = new ReactiveAsyncCommand();
OpenFileCommand.RegisterAsyncAction(_ =>
{
    var path = GetOpenFilePath(); // This needs to be on the UI thread
    if (String.IsNullOrEmpty(path))
        return;

    ProcessFile(path);
});

与此问题类似

Asynchronous command execution with user confirmation

但我不知道如何在这里应用这个答案。我需要将路径值传递给处理器。

我该怎么做?

1 个答案:

答案 0 :(得分:3)

黑客的方法是在ViewModel中创建OpenFileCommand,但在View中调用RegisterAsyncAction,这有点粗糙。

您可以做的另一件事是将一个接口注入ViewModel,该接口代表公共文件对话框(即打开文件选择器)。从测试的角度来看,这很好,因为您可以模拟用户做各种事情。我把它建模为:

public interface IFileChooserUI
{
    // OnError's if the user hits cancel, otherwise returns one item
    // and OnCompletes
    IObservable<string> GetOpenFilePath();
}

现在,您的异步命令变为:

OpenFileCommand.RegisterAsyncObservable(_ => 
    fileChooser.GetOpenFilePath()
        .SelectMany(x => Observable.Start(() => ProcessFile(x))));

或者如果你想摇滚等待(如果你使用的是RxUI 4.x和VS2012,你可以):

OpenFileCommand.RegisterAsyncTask(async _ => {
    var path = await fileChooser.GetOpenFilePath();
    await Task.Run(() => ProcessFile(path));
});