显示 Prism 区域中可用的模块
我想在我的应用程序加载时加载模块,并让它们将视图放入 区域(另请参阅这篇 MSDN 文章) 在 Shell(主视图)中。我目前正在按需加载一个模块,它工作得很好。 (我使用调用 this.moduleManager.LoadModule("ModuleB");
的按钮加载模块,其中 moduleManager
定义为 [Import(AllowRecomposition = false) ] private IModuleManager moduleManager;
这全部来自 ModularityWithMef.Desktop 示例应用程序。)以下是相关代码:
模块
[ModuleExport(typeof(ModuleB), InitializationMode = InitializationMode.OnDemand)]
public class ModuleB : IModule
{
[Import(AllowRecomposition = false)] private IRegionManager _regionManager;
/// <summary>
/// Initializes a new instance of the <see cref="ModuleB"/> class.
/// </summary>
public ModuleB()
{
}
/// <summary>
/// Notifies the module that it has be initialized.
/// </summary>
public void Initialize()
{
_regionManager.AddToRegion("ContentRegion", new ModuleBView());
}
}
XAML 区域
<TabControl Regions:RegionManager.RegionName="ContentRegion" />
当我更改为在可用时加载模块时 ([ModuleExport(typeof(ModuleB), InitializationMode = InitializationMode.WhenAvailable)]
),当引导程序创建 Shell 时,我收到一个 ModuleInitializeException,提示“此 RegionManager 不包含名为“ContentRegion”的区域。”这告诉我,在 Shell 中创建区域和模块初始化存在计时问题。
所以这是我的问题:如何在发现时向 Shell 区域注册模块的视图,而不必使用 OnDemand 初始化并手动加载模块?
I want to load modules when my app loads and have them put their views in a region (see also this MSDN article) in the Shell (the main view). I am currently loading a module on demand and it works just fine. (I load the module with a button that calls this.moduleManager.LoadModule("ModuleB");
where moduleManager
is defined as [Import(AllowRecomposition = false)] private IModuleManager moduleManager;
. This all comes from the ModularityWithMef.Desktop sample application.) Here's the relevant code:
Module
[ModuleExport(typeof(ModuleB), InitializationMode = InitializationMode.OnDemand)]
public class ModuleB : IModule
{
[Import(AllowRecomposition = false)] private IRegionManager _regionManager;
/// <summary>
/// Initializes a new instance of the <see cref="ModuleB"/> class.
/// </summary>
public ModuleB()
{
}
/// <summary>
/// Notifies the module that it has be initialized.
/// </summary>
public void Initialize()
{
_regionManager.AddToRegion("ContentRegion", new ModuleBView());
}
}
XAML region
<TabControl Regions:RegionManager.RegionName="ContentRegion" />
When I change to loading the module when available ([ModuleExport(typeof(ModuleB), InitializationMode = InitializationMode.WhenAvailable)]
), I get a ModuleInitializeException when the bootstrapper is creating the Shell saying "This RegionManager does not contain a Region with the name 'ContentRegion'." This tells me that there is a timing issue with the creation of the region in the Shell and the initialization of the module.
So here's my question: How do I register the module's view with the Shell's region upon discovery and without having to use OnDemand initialization and manually load the module?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
嗯,这是一个简单的答案,但由于某种原因,我很难找到。
IRegionManager
提供了一个RegisterViewWithRegion
方法,该方法采用返回视图的函数。这允许区域管理器在准备好时实例化视图(而不是使用立即发生的AddToRegion
)。因此,关键是在模块的Initialize
例程中使用该方法:在我弄清楚这一点的同时,我还想出了一个解决方法。当模块设置为
InitializationMode.OnDemand
时,Shell 可以导入IModuleManager
并在ContentRendered
中使用LoadModule
事件。这可确保该区域已添加到区域管理器中,并且模块可以毫无问题地添加其视图。如果您需要迭代可用模块,请使用此事件处理程序:Well this was an easy answer that was, for some reason, hard for me to find. The
IRegionManager
provides aRegisterViewWithRegion
method that takes a function that returns the view. This allows the region manager to instantiate the view when it is ready (as opposed to usingAddToRegion
, which happens immediately). So the key is to use that method in the module'sInitialize
routine:While I was figuring this out, I also came up with a workaround. When the module is set to
InitializationMode.OnDemand
, the Shell can import theIModuleManager
and useLoadModule
in theContentRendered
event. This ensures that the region has been added to the region manager and that the module can add its view without a problem. If you need to iterate through the available modules, use this event handler:我倾向于在引导程序中快乐的视图和区域
AggregateCatalog.Changed _handler - 在这里您知道您的模块已经加载并且 Shell 已经使用所有模块实例化。
I tend to merry Views and the Region in the bootstrapper, in the
AggregateCatalog.Changed _handler - this is where you know that your module is already loaded and Shell is already instantiated with all the modules.