Okra Best Practices for Using the OpenFilePicker

Aug 17, 2013 at 8:50 PM
What is the most Okra-friendly way to make use of the OpenFilePicker?

I have a button on a page that should open up an OpenFilePicker to allow the user to select a local file before navigating to another page. f the user cancels out of the OpenFilePicker, then no navigation should take place.

Where is the best place for this sort of code? If I put an ICommand property in the view model, and allow the button's Command property to bind to it, then I have to allow for the possibility of the user canceling out of the OpenFilePicker.

I am considering several different approaches here, and am interested in feedback on the approach that is most compatible with Okra's design philosophy.

Thank you!
Coordinator
Aug 18, 2013 at 9:12 PM
Hi,

I think the best way to do this is probably the simplest way, via a DelegateCommand. The underlying method can then simply call NavigateTo(...) if the user selects a file, or doesn't do any navigation is the user cancels. The next problem is how to pass the selected file to the target page (I assume that this is required). Since you should be able to recover from application suspension you cannot pass the StorageFile, and instead you should use the Windows.Storage.AccessCache.StorageApplicationPermissions class to convert the file into a token that you can later use to retrieve the item.

So in the source view-model I have an OpenFileCommand property that is bound to a button (set in an Initialize() method that is called from the constructor),
public ICommand OpenFileCommand { get; private set; }

private void Initialize()
{
    OpenFileCommand = new DelegateCommand(OpenFile);
}

private async void OpenFile()
{
    FileOpenPicker picker = new FileOpenPicker();
    picker.FileTypeFilter.Add(".jpg");

    StorageFile file = await picker.PickSingleFileAsync();

    if (file != null)
    {
        string fileToken = StorageApplicationPermissions.FutureAccessList.Add(file);
        NavigationManager.NavigateTo("ViewImage", fileToken);
    }
}
Note how if the user cancels the file open picker then 'file' is null and no navigation occurs - the file open picker just closes and the original page is still visible. If the user selects a file then this is stored in the FutureAccessList (NB: This is limited to 1000 items so you should remove items from this at some point in the future when you know they are no longer needed). This returns a string token that can be passed as the argument for navigation.

In the "ViewImage" view-model this implements the IActivatable<string, string> interface,
public async void Activate(string arguments, string state)
{
    StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(arguments);
    
    // Do something with 'file'
}
Hope this helps,
Andy