简体   繁体   English

从ContinueFileOpenPicker方法导航到另一个页面

[英]Navigate to a different page from ContinueFileOpenPicker method

I'm using the FilePicker for Windows Universal apps and I'm trying to launch the File Picker from MainPage.xaml and then navigate to a different page (LoadPhoto.xaml) to render the selected image. 我正在使用Windows Universal应用程序的FilePicker,并且尝试从MainPage.xaml启动文件选择器,然后导航到其他页面(LoadPhoto.xaml)以呈现选定的图像。

I initially implemented my app so that I'd navigate to LoadPhoto.xaml and then, as part of loading the page, I'd call the File Picker. 最初,我实现了我的应用程序,以便导航至LoadPhoto.xaml,然后,在加载页面时,我将调用文件选择器。 However that caused issues when resuming the app, so I moved the File Picker call out of the constructor. 但是,这在恢复应用程序时引起了问题,因此我将File Picker调用移出了构造函数。

In the newest implementation, I call the file picker from MainPage.xaml and then, if a photo has been selected, navigate to LoadPhoto.xaml. 在最新的实现中,我从MainPage.xaml调用文件选择器,然后,如果已选择照片,请导航至LoadPhoto.xaml。 However, there seems to be a race condition somewhere: Sometimes, the app stays on the MainPage after selecting a picture (it looks like it's actually navigating to the LoadPhoto page but something makes the Frame go back to the MainPage). 但是,某处似乎存在竞争状况:有时,应用程序在选择图片后仍停留在MainPage上(看起来实际上是在导航至LoadPhoto页面,但有些东西使Frame返回MainPage)。 Other times, the app successfully navigates to the LoadPhoto page and renders the image, but if I navigate back with the Back button and then press the Pick photo button again, the FilePicker is briefly shown and then the app crashes. 其他时候,该应用程序成功导航到LoadPhoto页面并渲染图像,但是如果我使用“后退”按钮向后导航,然后再次按“拾取照片”按钮,则会短暂显示FilePicker,然后该应用程序崩溃。 This behavior doesn't repro with VS attached. 附加了VS后,此行为无法复制。 Everything works fine while executing in Debug mode. 在“调试”模式下执行时,一切正常。

I think the root cause is that the ContinueFileOpenPicker code is executed from a worker thread, so I shouldn't call this.Frame.Navigate(typeof(LoadPhoto), file); 我认为根本原因是ContinueFileOpenPicker代码是从工作线程执行的,所以我不应该调用this.Frame.Navigate(typeof(LoadPhoto), file); from that thread. 从那个线程。 That call should be made from the main thread, but I'm not sure how to do that. 该调用应从主线程进行,但我不确定如何执行。

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

How can I navigate to a different page from the ContinueFileOpenPicker method? 如何从ContinueFileOpenPicker方法导航到其他页面? The full code with the repro is here . 带有repro的完整代码在这里

When you call to Frame.Navigate to go to the LoadPhoto page you are passing a complex object as a parameter: the file the user has picked. 当您调用Frame.Navigate进入LoadPhoto页面时,您正在传递一个复杂的对象作为参数:用户选择的文件。 When you go back to MainPage and start a new picker session your app gets suspended and SuspensionManager serializes the frame's state (see SaveFrameNavigationState method in that class). 当您返回MainPage并开始一个新的选择器会话时,您的应用将被挂起,并且SuspensionManager会序列化框架的状态(请参阅该类中的SaveFrameNavigationState方法)。 Unfortunately, the GetNavigationState method in Frame does not support serializing a complex object, but only simple ones like strings, integers or guids. 不幸的是,Frame中的GetNavigationState方法不支持序列化复杂对象,而仅支持序列,字符串或整数等简单对象。 This is documented in the Frame.Navigate method on MSDN. 在MSDN上的Frame.Navigate方法中对此进行了说明。

The reason you don't see the app crashing when you are debugging in VS is because (by default) the app doesn't get suspended in this scenario, so the code that throws the exception is never called. 在VS中进行调试时,看不到应用程序崩溃的原因是(默认情况下)在这种情况下应用程序不会挂起,因此永远不会调用引发异常的代码。 However, with no debugger attached, your app is suspended when you navigate away from it. 但是,没有连接调试器,当您离开应用程序时,该应用程序将被挂起。 To force the suspension, use the Lifecycle Events drop-down in the Debug Location toolbar once you have launched the picker session. 要强制暂停,启动选择器会话后,请使用“ 调试位置”工具栏中的“ 生命周期事件”下拉列表。

If you really need to save/restore the state of the frame, then you should avoid passing StorageFiles when navigating. 如果确实需要保存/恢复框架的状态,则应避免在导航时传递StorageFiles。 You can use FutureAccessList , pass the path to the file when navigating and load it in LoadPhoto. 您可以使用FutureAccessList ,在导航时将路径传递到文件,并将其加载到LoadPhoto中。

If you don't need (or want to use) what SuspensionManager has to offer, then you could get rid of it and keep passing a StorageFile object. 如果您不需要(或不想使用)SuspensionManager提供的功能,则可以摆脱它,并继续传递StorageFile对象。 However, keep in mind that if you do this a reference to that object will be kept in the navigation stack. 但是,请记住,如果执行此操作,则对该对象的引用将保留在导航堆栈中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM