PRISM и WPF как добавить модуль по требованию - PullRequest
9 голосов
/ 28 июня 2010

У меня есть набор вкладок в окне оболочки и один основной регион, который является контентом управления. У меня также есть четыре модуля, которые я хочу загрузить по требованию, когда выбрана определенная вкладка. Поэтому, когда выбран tab1, я хочу загрузить модуль A, когда выбран tab2, я хочу загрузить ModuleB и т. Д. Первый модуль загружается при запуске приложения. Проблема в том, что при смене вкладки ничего не происходит. Там нет ошибок жестких. Я использую эту версию руководства по составным приложениям prism для WPF и Silverlight - октябрь 2009 г.

Я попробовал этот подход:

Shell:

 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");
        }
}

Загрузчик:

  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;
    }

}

И модуль B, который я хочу загружать по требованию (я использовал эту закомментированную строку, поэтому я оставил ее здесь):

[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>();
    }
}

Что я здесь не так делаю? Как мне поступить?

Ответы [ 2 ]

4 голосов
/ 15 августа 2011

Я успешно использую загрузку модулей по требованию. в моем сценарии я загружаю их после входа пользователя в систему.

Для проверки работоспособности вашего проекта убедитесь, что файл ModuleB.dll находится в том же каталоге, что и ваша оболочка / приложение. (например, убедитесь, что он скопирован в каталог отладки, если вы находитесь в режиме отладки).

У меня имя модуля и dll модуля названы одинаково, я не уверен, является ли это требованием, но это соглашение, которое я придерживался.

мои загрузчики CreateModuleCatalog очень прост

protected override IModuleCatalog CreateModuleCatalog()
{
    ModuleCatalog catalog = new ConfigurationModuleCatalog();
    return catalog;

}

модули перечислены в моем файле app.config

<modules>
    <module assemblyFile="PatronModule.dll" moduleType="PatronModule.PatronModuleDefinition, PatronModule" moduleName="PatronModule" startupLoaded="false" />
</modules>

затем, когда я загружаю модули, я использую этот код

    IModuleManager moduleManager = _container.Resolve<IModuleManager>();
    ModulesConfigurationSection modules = ConfigurationManager.GetSection("modules") as ModulesConfigurationSection;
    foreach (ModuleConfigurationElement module in modules.Modules)
        moduleManager.LoadModule(module.ModuleName);

Загрузка модулей должна происходить в потоке графического интерфейса, поэтому при необходимости вам нужно использовать диспетчер для загрузки (это строка, которую я использую для нее)

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() => { LoadModulesOnGuiThread(); }));

надеюсь, это поможет

0 голосов
/ 07 июля 2010

Я не совсем уверен, но попробуйте установить InitializationMode в OnDemand при добавлении модуля, например так:

var catalog = new ModuleCatalog();
catalog.AddModule(typeof(ModuleA)).AddModule(typeof(ModuleB), InitializationMode.OnDemand);
...