如何重置Prism for Xamarin.Forms(view)导航堆栈?

时间:2016-10-26 23:46:06

标签: navigation stack xamarin.forms prism reset

当我尝试从我的应用发送电子邮件时,我正在解决Prism.Forms(v6.2.0)和Xamarin Messaging Plugin(Xam.Plugins.Messaging v3.2.1)之间的冲突。

以下代码 - 从我的一个ViewModel执行:

using Plugin.Messaging;

if (MessagingPlugin.EmailMessenger.CanSendEmail)
{
    var email = new EmailMessageBuilder()
        .To("test@testemail.com")
        .Subject("Email subject here!")
        .Body("Dear friend,\nI would like to say...\n\n\n")
        .Build();
    MessagingPlugin.EmailMessenger.SendEmail(email);
}

产生此错误 - 待发送的电子邮件永远不会显示在屏幕上:

  

警告:尝试提供< MFMailComposeViewController:0x108fb4400> on< Xamarin_Forms_Platform_iOS_PageRenderer:0x107de67c0>其视图不在窗口层次结构中!

我认为发生这种情况是因为Messaging插件的iOS特定部分有.GetVisibleViewController()方法,该方法查找具有可见视图的UIViewController以显示要发送的电子邮件;它正在寻找iOS不喜欢的视图控制器。

我想指出,我有几乎相同的代码(如上所示)在MVVM图案化的Xamarin.Forms应用程序中运行没有问题,不使用Prism.Forms [编辑:Brian L.指出下面的那个这个问题可能不是由棱镜引起的,我倾向于同意他的意见;它更可能与两个应用程序之间的“导航流程”的微小差异有关,即使电子邮件构建/发送代码是相同的]。执行MessagingPlugin.EmailMessenger.SendEmail(email);行时,屏幕上会弹出一封电子邮件,其中包含收件人,主题和正文;并使用发送或取消按钮。这在非Prism Xamarin.Forms应用程序中运行良好。

所以,我已经解决了这个问题,足以让.SendEmail(email)方法调用正常工作。我必须将我的X.F页面(即我的viewmodel的视图)传递给iOS特定的项目代码,以便在其上调用.CreateViewController()。我使用这个新的UIViewController作为其RootViewController创建一个UIWindow,然后创建该窗口.MakeKeyAndVisible()。我已经调整了Xam.Plugins.Messaging的代码,让我传入一个UIViewController来使用。发生.SendEmail(email)方法调用后,我处理新创建的UIWindow;这样在发送或取消电子邮件后我就看不到了。

这一切都有效,并允许我按预期使用Messaging插件的电子邮件发送功能。

我唯一剩下的问题是导航调用我的原始ViewModel的navigationService实例(即使用上面的代码尝试发送电子邮件的ViewModel)在发送电子邮件后都失败了。发送电子邮件后,我的view / viewmodel上的其他功能正常工作;但是对navigationService.GoBackAsync()navigationService.NavigateAsync()的调用失败并产生一个熟悉的错误:

  

警告:尝试出现< Xamarin_Forms_Platform_iOS_ModalWrapper:0x1359c21a0> on< Xamarin_Forms_Platform_iOS_PlatformRenderer:0x133df9640>其视图不在窗口层次结构中!

我相信我想做的就是重置我的Prism NavigationService(view)堆栈,使用类似的东西(Xamarin.Forms的代码,没有Prism):

Navigation.InsertPageBefore(new HomePage(), Navigation.NavigationStack.First());
Navigation.PopToRootAsync(true);

但我没有看到使用Prism NavigationService进行“导航堆栈更改操作”的方法。但也许其他人呢?

提前致谢...

1 个答案:

答案 0 :(得分:10)

  

我有一个几乎相同的代码(如上所示)在MVVM图案的Xamarin.Forms应用程序中运行没有问题,不使用Prism.Forms

几乎相同,不完全相同。我想提一下,Prism对MVVM没什么特别之处。它只是为您设置Page.BindingContext。就是这样。因此,如果您在没有Prism的应用程序中只使用View和VM,则使用Prism之间没有区别。

要回答您的问题,要重置导航堆栈,您只需使用绝对URI。

NavigateAsync("myapp:///NavigationPage/MainPage")

这相当于MainPage = new NavigationPage(new MainPage());

相关问题