WPF Prism 6.2(统一)-启动模块加载时如何注册事件

时间:2018-07-23 13:38:01

标签: wpf prism

我想在SplashScreen中显示一条消息,该模块正在加载... 但是,使用Prism-ModuleManager只能注册“ LoadModuleCompleted”事件。

我自己尝试使用Prism-Sources实现“ LoadModuleInitiated”的事件处理程序,但是没有运气... https://github.com/PrismLibrary/Prism/blob/Prism.v6.2.0/Source/Wpf/Prism.Wpf/Modularity/ModuleManager.cs

任何想法,当加载开始时如何获得事件?!

是否有一种方法可以为此添加一个自己的事件处理程序,而无需处理完整的棱柱源代码包?

1 个答案:

答案 0 :(得分:1)

我通过创建一个实现IModuleInitializer接口的ModuleInitializer类来完成此操作。如果在引导程序的ConfigureContainer方法中获得Prism的ModuleInitializer的句柄并将其注册为命名实例,则可以在自定义ModuleInitializer中获得其句柄并将其用于繁重的工作。这样做,您可以将自己注入到模块加载过程中。我已经看到了获取某个接口的句柄然后通过遏制使用它来在许多地方进行自定义操作的这种模式,所以我绝不是这种方法的原始作者。不确定是否能很好地描述它。希望以下代码可以帮助您理解这一点。

自定义模块初始化器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Modularity;
using Microsoft.Practices.Unity;

namespace GD.Common.Prism
{
   /// <summary>
   /// This class implements a custom Prism module initializer.  Having this allows us to monitor 
   /// the module loading/initialization progress so we can display applications startup progress, 
   /// and publish out an event letting the application and the associated modules when 
   /// initialization is complete.
   /// </summary>
   public class ModuleInitializer : IModuleInitializer
   {
      private readonly IUnityContainer mUnityContainer = null;
      private readonly IModuleInitializer mDefaultModuleUnitializer = null;
      private readonly IModuleCatalog mModuleCatalog = null;
      private List<ModuleInfo> mLoadedModules = new List<ModuleInfo>();

      /// <summary>
      /// Parameterized Constructor.  Parameters supplied by dependency injection.
      /// </summary>
      /// <param name="aUnityContainer">untity DI container</param>
      /// <param name="aModuleCatalog">the current module catalog</param>
      public ModuleInitializer(IUnityContainer aUnityContainer, IModuleCatalog aModuleCatalog)
      {
         mUnityContainer = aUnityContainer;
         mModuleCatalog = aModuleCatalog;

         // Retrieve the default module initializer.  We will utilize this implementation to perform
         // the actual loading.  We just want to be the middle man for status
         mDefaultModuleUnitializer = mUnityContainer.Resolve<IModuleInitializer>("defaultModuleInitializer");
      }

      public void Initialize(ModuleInfo moduleInfo)
      {
         // Custom Code HERE

         mDefaultModuleUnitializer.Initialize(moduleInfo);

         mLoadedModules.Add(moduleInfo);



      }
   }
}

引导程序更新

protected override void ConfigureContainer()
{
   base.ConfigureContainer();

   // Get the provided module initializer
   var defaultModuleInitializer = Container.Resolve<IModuleInitializer>();
   // Save it off so that our custom initializer can use it to do the heavy lifting
   Container.RegisterInstance<IModuleInitializer>("defaultModuleInitializer", defaultModuleInitializer);
   // register our implementation as the default
   Container.RegisterType<IModuleInitializer, GD.Common.Prism.ModuleInitializer>(new ContainerControlledLifetimeManager());
}

我希望这有助于实现您要完成的任务。