如何为Xamarin.Forms(视图)导航堆栈重置Prism?

Jer*_*lis 3 navigation stack prism reset xamarin.forms

当我尝试从我的应用程序发送电子邮件时,我正在解决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);
}
Run Code Online (Sandbox Code Playgroud)

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

警告:尝试在<Xamarin_Forms_Platform_iOS_PageRenderer:0x107de67c0>上显示<MFMailComposeViewController:0x108fb4400>,其视图不在窗口层次结构中!

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

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

所以,我已经解决了这个问题,足以使.SendEmail(email)方法调用正常工作.我必须将我的XF页面(即我的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_PlatformRenderer:0x133df9640>上显示<Xamarin_Forms_Platform_iOS_ModalWrapper:0x1359c21a0>,其视图不在窗口层次结构中!

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

Navigation.InsertPageBefore(new HomePage(), Navigation.NavigationStack.First());
Navigation.PopToRootAsync(true);
Run Code Online (Sandbox Code Playgroud)

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

提前致谢...

Bri*_*nas 11

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

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

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

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

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

  • 再次感谢,布赖恩。那解决了我的问题。而不是调用`navigationService.NavigateAsync("HomePage")`,我现在调用`navigationService.NavigateAsync("app:///HomePage")` - 一切正常。我查找了有关 Prism Absolute URI 的文档,我不清楚上面示例中的“myapp”是否是“魔术字符串”——或者需要为我的应用程序进行定制。但它似乎可以是“anystring:///HomePage”并且仍然有效。让我知道这是否是错误的。如果这有助于这个问题/回答的未来读者...... (3认同)