微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从Xamarin表单的棱镜模块中导航后,“具有给定名称的区域已经注册”

如何解决从Xamarin表单的棱镜模块中导航后,“具有给定名称的区域已经注册”

(我想说的是我使用EventAggregator解决这个问题-如文章底部所示-但我想深入了解为什么它不起作用我目前设置的方式)。

我有一个Xamarin Forms应用程序,其中我将Prism(版本8)用于Xamarin Forms(版本4.8)。 在此应用程序中,我正在使用表单的模块和区域。

我的主应用程序有一个MainPage(在NavigationPage中),其中有一个棱镜区,其中注入了视图。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TestPrismModules.Views.MainPage"
             xmlns:prism="http://prismlibrary.com"
             prism:viewmodelLocator.Autowireviewmodel="True"
             Title="{Binding Title}">

            <StackLayout Orientation="Vertical">
                    <FlexLayout prism:RegionManager.RegionName="FlexRegion"/>
            </StackLayout>
</ContentPage>

我有一个模块(AuthModule),它通过AuthenticationService处理身份验证和登录。 该模块还包含一个LoginPage,其等价LoginPageviewmodellogout中的AuthenticationService方法将注销并向NavigateAsync

进行LoginPage
public class AuthenticationService : IAuthenticationService
{
    private readonly INavigationService _navigationService;

    public AuthenticationService(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public void logout()
    {
        // logging out code goes here
        _navigationService.NavigateAsync("/LoginPage");
    }
}

这是AuthModule模块代码

public class AuthModuleModule : IModule
{
    public void OnInitialized(IContainerProvider containerProvider)
    {
    }

    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<IAuthenticationService,AuthenticationService>();
        containerRegistry.RegisterRegionServices();
        containerRegistry.RegisterForNavigation<LoginPage,LoginPageviewmodel>();
    }
}

启动应用程序后,导航到的第一页是LoginPage(提醒-AuthModule中的)。到目前为止一切顺利。

我有一个要求,如果用户在恢复或重新激活该应用程序后立即将其停用,则该用户必须注销并必须重新登录。为此,我重写了OnResume方法,解析了AuthenticationService一个实例,并在其中调用logout方法

public partial class App
{
    public App(IPlatformInitializer initializer)
        : base(initializer)
    {
    }

    protected override async void OnInitialized()
    {
        InitializeComponent();
        var ea = Container.Resolve<IEventAggregator>();
        ea.GetEvent<LoggedInEvent>().Subscribe(OnUserAuthenticated);
        await NavigationService.NavigateAsync("/LoginPage",null,true,true);
    }

    private void OnUserAuthenticated()
    {
        NavigationService.NavigateAsync("/NavigationPage/MainPage");
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {

        containerRegistry.RegisterRegionServices();
        containerRegistry.RegisterSingleton<IAppInfo,AppInfoImplementation>();

        containerRegistry.RegisterForNavigation<NavigationPage>();
        containerRegistry.RegisterForNavigation<MainPage,MainPageviewmodel>();
        
    }

    protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
    {
        base.ConfigureModuleCatalog(moduleCatalog);
        moduleCatalog.AddModule<TestModule1Module>();
        moduleCatalog.AddModule<AuthModuleModule>();
    }


    // Want to force user to login when the app resumes
    protected override void OnResume()
    {
        base.OnResume();

        // logout and redirect to Login Page
        var authService = Container.Resolve<IAuthenticationService>();
        authService.logout();
    }
 }

这一切工作正常且繁琐-直到用户尝试再次登录并获得可怕的“ 具有给定名称的区域已注册

直接从主应用程序导航到LoginPage(而不是通过AuthenticationService),然后重新登录后回到MainPage效果很好,但我没有关于已注册地区的例外。知道了这一点,我有一种解决方法,可以使用EventAggregator订阅LoggedOut事件(在App.xaml.cs中),然后从AuthenticationService发布该事件并调用{ {1}}来自订阅

我怀疑我可能会得到有关使用范围区域或类似区域的建议,但我不确定该怎么做。

我这里有一个示例项目来测试是否有帮助:https://github.com/tomaswinston/TestPrismModulesAuth

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。