2013-04-13 39 views
1

我想注册一个打开文件并处理它的异步命令。来自ReactiveAsyncCommand的UI访问

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

相似,但我不知道如何在这里适用这个问题的答案。我需要将路径值传递给处理器。

我该怎么做?

回答

3

破解方法是在ViewModel中创建OpenFileCommand,但在视图中调用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)); 
}); 
+0

我目前正在使用对话服务的接口,我只是没有在简单的问题中包括它。目前虽然它只返回一个字符串,而不是任务或可观察的。太好了,谢谢! –