Continuation in a Prism WP8.1 App

Mar 2, 2015 at 7:37 PM
Edited Mar 2, 2015 at 7:39 PM
Hi.

Is there some example available that shows how to continue an app after returning from a FileOpenPicker in WP8.1?

I.e. after calling
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");

openPicker.PickSingleFileAndContinue();
in my ViewModel, how do I handle continuation?

I've had a look at the ContinuationManager and SuspensionManager classes, but with Prism handling app lifecycle events, applying those classes does not seem so straightforward. An example would be extremely useful.

-jgoe
Mar 3, 2015 at 2:00 PM
There is nothing built in to Prism to handle that scenario, but that doesn't mean you can't just follow similar guidance as is outlined here:
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn631755.aspx

Prism for Windows Runtime does have its own SuspensionManager like functionality under the covers, that is the SessionStateService. So if you wanted to fully integrate the handling, you could possibly do it through the SessionStateService instead of using a SuspensionManager like that guidance outlines. But there is no harm in having your own SuspensionManager for that handling.
Mar 3, 2015 at 10:21 PM
Hi Brian.

Thank you. This gives me some reassurance. I have already been working through the guide you mentioned but was not sure whether that is the right approach for a Prism app. I got the impression that Prism is already doing a pretty good job on handling the app state, so the functionality provided by the SuspensionManager seemed redundant. Maybe I'm oversimplifying, but my idea was to use the ContinuationManager directly to call ContinueFileOpenPicker() and not worry about the SuspensionManager at all.

In App.xaml.cs:
protected override void OnActivated(IActivatedEventArgs args) {
    base.OnActivated(args);
    continuationManager = new ContinuationManager();
    var continuationEventArgs = args as IContinuationActivatedEventArgs;
    if (continuationEventArgs != null) {
        continuationManager.Continue(continuationEventArgs);
    }
    Window.Current.Activate();
}
The Continue() Method in the ContinuationManager then decides how to continue based on the event arguments:
(...)
case ActivationKind.PickFileContinuation:
    var fileOpenPickerPage = rootFrame.Content as IFileOpenPickerContinuable;
    if (fileOpenPickerPage != null) {
        fileOpenPickerPage.ContinueFileOpenPicker(args as FileOpenPickerContinuationEventArgs);
    }
    break;
(...)
One problem here is that the ContinuationManager expects the ContinueFileOpenPicker() method in the code behind. Now it is in the ViewModel, which seemed more consistent with the MVVM patttern. Should the implementation of IFileOpenPickerContinuable better be moved into the View, or should this call be forwarded to the ViewModel, and how can that be done?

Thanks and regards,
-jgoe
Mar 4, 2015 at 11:31 AM
I would approach it similar to how the navigation APIs work - if you are dealing with an API that only knows about the view, define an interface that the ViewModel can implement (IFileOpenPickerHandler or something) that lets you dispatch the information in the args to the ViewModel, then have the immediate handling code try to cast the DataContext of the Page to that interface, and as long as it supports it, call the interface. If it does not, then just call the normal API on the page.
Marked as answer by jgoe on 3/4/2015 at 8:23 AM
Mar 4, 2015 at 3:23 PM
Thank you, Brian. You put me on the right track. Took me a moment to wrap my head around it, but it turns out most of it is already there. At the end, it took a small modification in the Continue() method, and the continuation of the file picker in the ViewModel was hooked up.
case ActivationKind.PickFileContinuation:
    var page = rootFrame.Content as Page;
    var fileOpenPickerContinuable = page.DataContext as IFileOpenPickerContinuable;
    if (fileOpenPickerContinuable != null) {
        fileOpenPickerContinuable.ContinueFileOpenPicker(args as FileOpenPickerContinuationEventArgs);
    }
    break;
-jgoe