PRISM and WPF how to add a module on demand
我的shell窗口中有一组选项卡,而一个主要区域whicxh是contentcontrol。 当选择某个选项卡时,我还想按需加载四个模块。 因此,当选择tab1时,我要加载模块A,当选择tab2时,我要加载模块B,等等。第一个模块在应用程序启动时加载。 问题是,当我更改选项卡时,什么也没有发生。 没有艰难的错误。 我正在使用此版本的WPF和Silverlight棱镜综合应用指南-2009年10月。
我尝试了这种方法:
贝壳:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public partial class Shell : RibbonWindow, IShellView { private readonly IRegionManager regionManager; private readonly IModuleManager moduleManager; public Shell(IModuleManager moduleManager) { this.moduleManager = moduleManager; InitializeComponent(); } public void ShowView() { this.Show(); } private void onTabSelection(object sender, RoutedEventArgs e) { this.moduleManager.LoadModule("ModuleB"); } } |
引导程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public partial class MyBootstrapper : UnityBootstrapper { protected override IModuleCatalog GetModuleCatalog() { var catalog = new ModuleCatalog(); catalog.AddModule(typeof(ModuleA)).AddModule(typeof(ModuleB)); return catalog; } protected override void ConfigureContainer() { Container.RegisterType<IShellView, Shell>(); base.ConfigureContainer(); } protected override DependencyObject CreateShell() { ShellPresenter presenter = Container.Resolve<ShellPresenter>(); IShellView view = presenter.View; view.ShowView(); return view as DependencyObject; } } |
我希望能够按需加载的moduleB(我曾经使用此注释行,这就是为什么我将其留在这里的原因):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [Module(ModuleName ="ModuleB", OnDemand = true)] public class ModuleB : IModule { private readonly IUnityContainer _container; private readonly IRegionManager _regionManager; public ModuleB(IUnityContainer container, IRegionManager regionManager) { _container = container; _regionManager = regionManager; } public void Initialize() { _regionManager.Regions["MainRegion"].Add(new ModuleBView()); this.RegisterViewsAndServices(); // this._regionManager.RegisterViewWithRegion(RegionNames.MainRegion, () => _container.Resolve<MissionProfileView>()); } protected void RegisterViewsAndServices() { _container.RegisterType<Modules.ModuleBView>(); } } |
我在这里做错了什么? 我应该如何进行?
我成功使用了按需加载模块。在我的情况下,我在用户登录后加载它们。
为了对项目进行完整性检查,请确保ModuleB.dll与Shell /应用程序位于同一目录中。 (例如,如果您处于调试模式,请确保将其复制到调试目录)。
我有相同的模块名称和模块dll,我不确定这是否是必需项,但是我一直坚持的约定。
我的引导程序CreateModuleCatalog非常简单
1 2 3 4 5 6 | protected override IModuleCatalog CreateModuleCatalog() { ModuleCatalog catalog = new ConfigurationModuleCatalog(); return catalog; } |
模块列在我的app.config文件中
1 2 3 | <modules> <module assemblyFile="PatronModule.dll" moduleType="PatronModule.PatronModuleDefinition, PatronModule" moduleName="PatronModule" startupLoaded="false" /> </modules> |
然后当我加载模块时我使用此代码
1 2 3 4 | IModuleManager moduleManager = _container.Resolve<IModuleManager>(); ModulesConfigurationSection modules = ConfigurationManager.GetSection("modules") as ModulesConfigurationSection; foreach (ModuleConfigurationElement module in modules.Modules) moduleManager.LoadModule(module.ModuleName); |
模块的加载必须在GUI线程上进行,因此,如果需要,您需要使用分派器进行加载(这是我使用的行)
1 | Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() => { LoadModulesOnGuiThread(); })); |
希望这可以帮助
我不太确定,但是尝试在添加模块时将InitializationMode设置为OnDemand,如下所示:
1 2 | var catalog = new ModuleCatalog(); catalog.AddModule(typeof(ModuleA)).AddModule(typeof(ModuleB), InitializationMode.OnDemand); |