如何加载模块并导航到该模块?棱镜

本文关键字:模块 导航 棱镜 加载 何加载 | 更新日期: 2023-09-27 18:26:21

我有两个模块:ModuleLoggingModuleItems。我的Shell有声明:

<Grid>
   <DockPanel LastChildFill="True">
    <ContentControl  DockPanel.Dock="Top" prism:RegionManager.RegionName="{x:Static inf:RegionNames.TheUpperRegion}" Margin="5" />
    <ContentControl prism:RegionManager.RegionName="{x:Static inf:RegionNames.TheBottomRegion}" Margin="5"/>                     
   </DockPanel>
    <ContentControl prism:RegionManager.RegionName="{x:Static inf:RegionNames.TheWholeRegion}" Margin="5"  />
</Grid>

首先加载ModuleLogging。然后,如果用户通过了身份验证,我想加载ModuleItems。正如我正确理解的那样,我应该实例化

我的引导类:

protected override IModuleCatalog CreateModuleCatalog()
{
   ModuleCatalog catalog = new ModuleCatalog();
   catalog.AddModule(typeof(ModuleLogging));
   //I've not added ModuleItems as I want to check whether the user is authorized
   return catalog;
}   

我尝试从ModuleLogging:调用ModuleItems

Uri viewNav = new Uri("ModuleItems", UriKind.Relative);
regionManager.RequestNavigate(RegionNames.TheUpperRegion, viewNav);
regionManager.RequestNavigate(RegionNames.TheBottomRegion, viewNav); 

但我的ModuleLoggingLoggingView并没有被ModuleItemsToolBarViewModuleItemsDockingView所取代。我只是在ContentControls中分别看到System.ObjectSystem.Object,而不是控件,因为LoggingView是透明的。

是的,我知道内存中没有像ModuleItems这样的对象。

如何根据需要加载模块并导航到视图?

如何加载模块并导航到该模块?棱镜

您可能需要对它们进行排序以使其正常工作:

  • 将模块添加到目录
  • 按需加载模块
  • 注册将在区域中显示的视图(或视图模型)
  • 请求导航到您的视图

让我们看看的顺序

将模块添加到目录

我看不出有任何理由不将您的模块添加到目录中,但是,在身份验证之后,您可能不想要的是初始化模块。要按需初始化模块,您可以将其添加到带有OnDemand:标志的目录中

模块将在请求时初始化,而不是自动初始化在应用程序启动时。

在您的引导程序中:

protected override void ConfigureModuleCatalog()
{
    Type ModuleItemsType = typeof(ModuleItems);
    ModuleCatalog.AddModule(new ModuleInfo()
    {
        ModuleName = ModuleItemsType.Name,
        ModuleType = ModuleItemsType.AssemblyQualifiedName,
        InitializationMode = InitializationMode.OnDemand
    });

按需加载模块

然后在验证成功后,您可以初始化您的模块:

private void OnAuthenticated(object sender, EventArgs args)
{
    this.moduleManager.LoadModule("ModuleItems");    
}

其中moduleManagerMicrosoft.Practices.Prism.Modularity.IModuleManager的实例(最好注入到类构造函数)

注册您的视图

您还需要在容器中注册要导航到的视图(如果您首先使用的是视图模型,则为视图模型)。最好的方法可能是初始化模块ModuleItems,只需确保容器被注入其构造函数:

public ModuleItems(IUnityContainer container)
{
    _container = container;
}
public void Initialize()
{
    _container.RegisterType<object, ToolBarView>(typeof(ToolBarView).FullName);
    _container.RegisterType<object, DockingView>(typeof(DockingView).FullName);
    // rest of initialisation
}

请注意,为了使RequestNavigate工作,您必须将视图注册为对象,并且必须提供其全名作为名称参数。

同样使用模块作为导航目标(就像你在这里所做的那样:Uri viewNav = new Uri("ModuleItems", UriKind.Relative);可能不是最好的主意。模块对象通常只是一个临时对象,一旦模块初始化,默认情况下就会被丢弃。

请求导航

最后,一旦你的模块被加载,你就可以请求导航了。您可以使用上面提到的moduleManager挂接到LoadModuleCompleted事件:

this.moduleManager.LoadModuleCompleted += (s, e)
    {
        if (e.ModuleInfo.ModuleName == "ModuleItems")
        {
            regionManager.RequestNavigate(
                RegionNames.TheUpperRegion,
                typeof(ToolBarView).FullName), 
                result => 
                { 
                   // you can check here if the navigation was successful
                });
            regionManager.RequestNavigate(
                RegionNames.TheBottomRegion,
                typeof(DockingView).FullName));
        }
    }

最伟大的马格努斯·蒙廷帮助我解决了这个问题:

此代码位于ModuleLogging:的LoggingViewmodel

private void DoLogin(object obj)
    {
        ShowAnotherView = false;
        if (UserName == "1" && UserPassword == "1")
        {                
            container.RegisterType<Object, TheUpperControl>("ModuleItems");
            Uri viewNav = new Uri("ModuleItems", UriKind.Relative);
            regionManager.RequestNavigate(RegionNames.TheUpperRegion, viewNav);
            regionManager.RequestNavigate(RegionNames.TheBottomRegion, viewNav);
            LoadTheOtherModule(); //load the other module
            var loginView = regionManager.Regions[RegionNames.TheWholeRegion].Views.ElementAt(0);
            regionManager.Regions[RegionNames.TheWholeRegion].Remove(loginView); //remove the login view
            //MessageBox.Show("");    
        }
        else
            ShowPromptingMessage = true;
    }
    private void LoadTheOtherModule()
    {
        Type moduleType = typeof(ModuleItems.ModuleItemsModule);
        ModuleInfo mi = new ModuleInfo()
        {
            ModuleName = moduleType.Name,
            ModuleType = moduleType.AssemblyQualifiedName,
        };
        IModuleCatalog catalog = container.Resolve<IModuleCatalog>();
        catalog.AddModule(mi);
        catalog.Initialize();
        IModuleManager moduleManager = container.Resolve<IModuleManager>();
        moduleManager.LoadModule(moduleType.Name); //run Initialize() of the other module
    }

它就像一个符咒!:)