Reputation: 71856
I want to register an async command that opens a file and processes it.
OpenFileCommand = new ReactiveAsyncCommand();
OpenFileCommand.RegisterAsyncAction(_ =>
{
var path = GetOpenFilePath(); // This needs to be on the UI thread
if (String.IsNullOrEmpty(path))
return;
ProcessFile(path);
});
Similar to this question
Asynchronous command execution with user confirmation
But I'm not sure how to apply that answer here. I need to pass the path value to the processor.
How would I do this?
Upvotes: 1
Views: 563
Reputation: 74654
The hack way is to create OpenFileCommand in the ViewModel but call RegisterAsyncAction
in the View, which is kind of gross.
Another thing you can do would be to inject an interface into the ViewModel that represents the common file dialog (i.e. the open file chooser). This is great from a testing perspective because you can simulate the user doing various things. I'd model it as:
public interface IFileChooserUI
{
// OnError's if the user hits cancel, otherwise returns one item
// and OnCompletes
IObservable<string> GetOpenFilePath();
}
Now, your async command becomes:
OpenFileCommand.RegisterAsyncObservable(_ =>
fileChooser.GetOpenFilePath()
.SelectMany(x => Observable.Start(() => ProcessFile(x))));
Or if you want to rock the awaits (which if you're using RxUI 4.x and VS2012, you can):
OpenFileCommand.RegisterAsyncTask(async _ => {
var path = await fileChooser.GetOpenFilePath();
await Task.Run(() => ProcessFile(path));
});
Upvotes: 3