xamarin.forms - 从 Xamarin 表单的 Prism 中的模块导航后“具有给定名称的区域已注册”
问题描述
(我只想说我有一个解决方法,使用EventAggregator
- 如帖子底部所示 - 但我想深入了解为什么它不能按照我目前设置的方式工作)。
我有一个 Xamarin Forms 应用程序,我在其中使用 Prism(版本 8)作为 Xamarin Forms(版本 4.8)。在这个应用程序中,我使用表单的模块和区域。
我的主要应用程序有一个MainPage
(在 a 中NavigationPage
),其中我有一个 Prism 区域,视图被注入其中。
<?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
with equivelant LoginPageViewModel
。中的Logout
方法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
方法,解析了 my 的一个实例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
重新登录后返回到 ,工作正常,我没有得到关于 Region 已经注册的异常。知道了这一点,我有一个解决方法,我使用EventAggregator
订阅LoggedOut
事件(在 中App.xaml.cs
)并从 发布该事件并从订阅中AuthenticationService
调用NavigateAsync
。
我怀疑我可能会收到有关使用 Scoped 区域或类似区域的建议,但我不确定如何去做。
我在这里有一个示例项目来测试它是否有帮助:https ://github.com/tomaswinston/TestPrismModulesAuth
解决方案
推荐阅读
- flutter - 我如何在颤动中设计上面的产品卡
- jmeter - 从 JMeter 中的 CSV 文件中选择随机路径
- python - " 在 Python 中计算接近标准 "
- perl - 如何从Perl中的哈希中获取小于阈值的第一个值
- string - 给定一个二进制字符串“10110”。查找所有设置位数 >= n 的子串的计数
- c# - 统一分步执行条件
- angular - 从哪里导入 NgxMqttServiceConfig?Angular 测试中的 NullInjectorError 错误
- sql-server - 事实表的行数或大小
- github - 我的 github 页面已连接到我的域,但没有反映我的代码的网站。该怎么办?
- angular - Angular Universal (SSR) 不知道使用自定义 http (rxjs ajax, axios) 的请求