从ContinueFileOpenPicker方法导航到其他页面

我正在使用FilePicker for Windows Universal应用程序,我正在尝试从MainPage.xaml启动文件选择器,然后导航到另一个页面(LoadPhoto.xaml)以呈现所选图像。

我最初实现了我的应用程序,以便我导航到LoadPhoto.xaml然后,作为加载页面的一部分,我将调用文件选择器。 但是,这会在恢复应用时导致问题,因此我将File Picker调用移出构造函数。

在最新的实现中,我从MainPage.xaml调用文件选择器,然后,如果已选择照片,则导航到LoadPhoto.xaml。 然而,某处似乎存在竞争条件:有时,应用程序在选择图片后停留在MainPage上(看起来它实际上导航到LoadPhoto页面,但有些东西使Frame返回到MainPage)。 其他时候,应用程序成功导航到LoadPhoto页面并呈现图像,但如果我使用“后退”按钮导航回来,然后再次按“选择照片”按钮,则会短暂显示FilePicker,然后应用程序崩溃。 VS附加此行为不会重现。 在调试模式下执行时一切正常。

我认为根本原因是ContinueFileOpenPicker代码是从一个工作线程执行的,所以我不应该调用this.Frame.Navigate(typeof(LoadPhoto), file); 从那个线程。 该调用应该来自主线程,但我不知道该怎么做。

不幸的是,这并不能解决问题: await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Norm‌​al, () => { this.Frame.Navigate(typeof(LoadPhoto), file); });

如何从ContinueFileOpenPicker方法导航到其他页面? repro的完整代码就在这里 。

当您调用Frame.Navigate转到LoadPhoto页面时,您将传递一个复杂对象作为参数:用户选择的文件。 当您返回MainPage并开始一个新的选择器会话时,您的应用程序将被暂停,SuspensionManager会序列化该帧的状态(请参阅该类中的SaveFrameNavigationState方法)。 不幸的是,Frame中的GetNavigationState方法不支持序列化复杂对象,而只支持简单的对象,如字符串,整数或guids。 这在MSDN上的Frame.Navigate方法中有记录。

在VS中调试时看不到应用程序崩溃的原因是(默认情况下)应用程序在此方案中不会被挂起,因此永远不会调用抛出exception的代码。 但是,如果没有附加调试器,当您离开它时,您的应用程序将被暂停。 要强制暂停,请在启动选取器会话后使用“ 调试位置”工具栏中的“ 生命周期事件”下拉列表。

如果您确实需要保存/恢复帧的状态,那么您应该避免在导航时传递StorageFiles。 您可以使用FutureAccessList ,在导航时将路径传递给文件并在LoadPhoto中加载它。

如果您不需要(或想要使用)SuspensionManager提供的内容,那么您可以摆脱它并继续传递StorageFile对象。 但是,请记住,如果这样做,对该对象的引用将保留在导航堆栈中。