2013-04-13 70 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

我目前正在使用對話服務的接口,我只是沒有在簡單的問題中包括它。目前雖然它只返回一個字符串,而不是任務或可觀察的。太好了,謝謝! –