.net 在棱镜区域中显示模块(如果可用)
我想在我的应用程序加载时加载模块,并让它们将视图放在Shell(主视图)中的一个(另请参见)中。我目前正在按需加载一个模块,它工作正常。(我用一个按钮加载模块,该按钮调用.net 在棱镜区域中显示模块(如果可用),.net,wpf,module,prism,mef,.net,Wpf,Module,Prism,Mef,我想在我的应用程序加载时加载模块,并让它们将视图放在Shell(主视图)中的一个(另请参见)中。我目前正在按需加载一个模块,它工作正常。(我用一个按钮加载模块,该按钮调用this.moduleManager.LoadModule(“ModuleB”);其中moduleManager定义为[Import(AllowRecomposition=false)]私有IModuleManager moduleManager;。这些都来自示例应用程序。)以下是相关代码: 模块 [ModuleExport(t
this.moduleManager.LoadModule(“ModuleB”);
其中moduleManager
定义为[Import(AllowRecomposition=false)]私有IModuleManager moduleManager;
。这些都来自示例应用程序。)以下是相关代码:
模块
[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());
}
}
[ModuleExport(typeof(ModuleB),InitializationMode=InitializationMode.OnDemand)]
公共类模块B:IModule
{
[导入(AllowRecomposition=false)]专用IRegionManager\u regionManager;
///
///初始化类的新实例。
///
公共模块b()
{
}
///
///通知模块它已被初始化。
///
公共无效初始化()
{
_regionManager.AddToRegion(“ContentRegion”,newModuleView());
}
}
XAML区域
<TabControl Regions:RegionManager.RegionName="ContentRegion" />
当我更改为在可用时加载模块([ModuleExport(typeof(ModuleB),InitializationMode=InitializationMode.WhenAvailable)]
)时,当引导程序创建Shell时,我会得到一个ModuleInitializeException,其中说明“此RegionManager不包含名为“ContentRegion”的区域。”这告诉我,在Shell中创建区域和初始化模块时存在时间问题
因此,我的问题是:如何在发现时将模块的视图注册到Shell的区域,而不必使用OnDemand初始化并手动加载模块?这是一个简单的答案,由于某种原因,我很难找到。
IRegionManager
提供了一个RegisterViewWithRegion
方法,该方法采用返回视图的函数。这允许区域管理器在视图准备就绪时实例化视图(而不是使用立即发生的AddToRegion
)。因此,关键是在模块的初始化例程中使用该方法:
public void Initialize()
{
_regionManager.RegisterViewWithRegion("ContentRegion", () => new ModuleBView());
}
在我弄明白这一点的同时,我也想出了一个解决办法。当模块设置为InitializationMode.OnDemand
时,Shell可以导入IModuleManager
并在ContentRendered
事件中使用LoadModule
。这样可以确保区域已添加到区域管理器,并且模块可以毫无问题地添加其视图。如果需要遍历可用模块,请使用此事件处理程序:
public Shell()
{
InitializeComponent();
ContentRendered += (o, eventArgs) =>
{
foreach (var moduleInfo in _moduleCatalog.Modules)
{
_moduleManager.LoadModule(moduleInfo.ModuleName);
}
};
}
我倾向于在bootstrapper中,在
AggregateCatalog.Changed _handler-在这里,您知道您的模块已经加载,Shell已经与所有模块一起实例化。谢谢发布。:)