【问题标题】:Prism: How to load Default View in Shell Region with Unity BootstrapperPrism:如何使用 Unity Bootstrapper 在 Shell 区域中加载默认视图
【发布时间】:2017-05-13 17:09:44
【问题描述】:

当我查看 Prism Navigation QuickStart 演示时,它使用 Mef Bootstrapper 并使用 Shell.xaml.cs 文件中的 IPartImportsSatisfiedNotification 接口将默认视图加载到 Shell 区域,如下所示.

[Export]
public partial class Shell : UserControl, IPartImportsSatisfiedNotification
{
    ...

    public void OnImportsSatisfied()
    {
        this.ModuleManager.LoadModuleCompleted +=
            (s, e) =>
            {
                if (e.ModuleInfo.ModuleName == EmailModuleName)
                {
                    this.RegionManager.RequestNavigate(
                        RegionNames.MainContentRegion,
                        InboxViewUri);
                }
            };
    }
}

在我的项目中,我使用 Unity Bootstrapper 并尝试参考这个演示来加载默认视图。正如预期的那样,它完全不起作用。

请与我分享关于“如何使用 Unity Bootstrapper 将默认视图注入 Shell 区域”的建议和一些建议。

【问题讨论】:

    标签: c# wpf shell prism prism-6


    【解决方案1】:

    假设您的引导程序中有一个 CreateModuleCatalog 覆盖,您可以使用它将模块添加到目录中。

    catalog.AddModule(typeof(YourModule));
    

    在 YourModule Initiaize 覆盖中,注册您想要显示的视图,如下所示。

    使用视图发现:

    RegionManager.RegisterViewWithRegion("YourRegion", typeof(YourView));
    

    使用视图注入(如果您想要更多控制,或者需要一个作用域区域等):

    IRegion region = _region_manager.Regions["YourRegion"];
    var view = _container.Resolve<YourView>();
    region.Add(view, typeof(YourView).FullName);
    region.Activate(view);
    

    这种注入方式需要你有一个对区域管理器的引用,并且你已经在Unity容器中注册了视图,并且你对容器有一个引用

    只要 YourRegion 区域在您的 Shell xaml 中,并且在运行时可见,YourView 就会显示在其中。

    Hello World 快速入门也显示了这一点,并使用 Unity 容器。

    https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/HelloWorld

    【讨论】:

      【解决方案2】:

      只需将视图添加到模块中的区域即可。初始化视图的来源。

      【讨论】:

      • 如果 View 也用于导航怎么办?
      • 我的意思是我想在显示 shell 之前加载所有模块。因此,我可以在应用程序运行时获得良好的速度。我已经看过这个答案:stackoverflow.com/a/5403079/2284240。但我不知道如何初始化模块。
      【解决方案3】:

      我遇到过这个问题 如果你使用 prism.Unity,wpf

      你可以设置

      protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
      {
          var factory = base.ConfigureDefaultRegionBehaviors();
          factory.AddIfMissing("AutoPopulateExportedViewsBehavior",typeof(AutoPopulateExportedViewsBehavior));
          return factory;
      }
      

      为“AutoPopulateExportedViewsBehavior”添加新类后

      public class AutoPopulateExportedViewsBehavior : RegionBehavior
      {
          public static string Key {
              get;
          } = nameof( AutoPopulateExportedViewsBehavior );
      
          protected override void OnAttach()
          {
              this.Region.ActiveViews.CollectionChanged += this.ActiveViews_CollectionChanged;
          }
          private void ActiveViews_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e )
          {
              switch ( e.Action )
              {
              case NotifyCollectionChangedAction.Add:
                  Action<IRegionManagerAware> setRegionManager = x => x.RegionManager = this.Region.RegionManager;
                  MvvmHelpers.ViewAndViewModelAction( e.NewItems[0], setRegionManager );
                  break;
              case NotifyCollectionChangedAction.Remove:
                  Action<IRegionManagerAware> resetRegionManager = x => x.RegionManager = null;
                  MvvmHelpers.ViewAndViewModelAction( e.OldItems[0], resetRegionManager );
                  break;
              }
          }
      }
      

      你需要一个接口来找到“RegionManager”

      public interface IRegionManagerAware
      {
          IRegionManager RegionManager {
              get; set;
          }
      }
      

      最后,告诉程序你需要一个默认视图,

      public class ModulesModule : IModule
      {
          IRegionManager  _regionManager;
          IUnityContainer _container;
          public ModulesManagementModule( RegionManager regionManager, IUnityContainer container )
          {
              _regionManager  = regionManager;
              _container  = container;
          }
          public void Initialize()
          {
              _container.RegisterTypeForNavigation<ViewA>();
              _regionManager.RequestNavigate("ViewA", "ViewA" );
          }
      }
      

      想法和解决方案来自: enter link description here

      通过这个例子,你可以得到导航的默认视图

      【讨论】:

        【解决方案4】:

        您必须加载/注册您的模块。您可以通过多种方式做到这一点。

        在代码中注册/加载

        bootstrapper.cs

        protected override void ConfigureModuleCatalog() 
        {
            Type ModuleAType = typeof(ModuleAModule);
            ModuleCatalog.AddModule(new ModuleInfo()
            {
                ModuleName = moduleAType.Name,
                ModuleType = moduleAType.AssemblyQualifiedName,
                InitializationMode = InitializationMode.WhenAvailable
            });
        }
        

        从目录注册/加载

        bootstrapper.cs

        protected override IModuleCatalog CreateModuleCatalog() 
        {
            return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
        }
        

        在 bin\Debug 目录下创建Modules 目录,并将ModuleA.dll 文件复制/粘贴到该目录。

        ModuleAModulle.cs中可以定义模块名和初始化方法:

        [Module(ModuleName="ModuleA", OnDemand=true)]
        public class ModuleAModule : IModule 
        {
            public void Initialize()
            {
                throw new NotImplementedException();
            }
        }
        

        从 XAML 文件注册/加载

        将新的资源字典添加到您的 shell 项目并将构建操作设置为资源。 (在这个例子中它被称为XamlCatalog.xaml

        <Modularity:ModuleCatalog
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:Modularity="clr-namespace:Microsoft.Practices.Prism.Modularity;assembly=Microsoft.Practices.Prism">
        
            <Modularity:ModuleInfo Ref="file://ModuleA.dll" ModuleName="ModuleA" ModuleType="ModuleA.ModuleAModule, ModuleA, Version=1.0.0.0" InitializationMode="WhenAvailable" />
        
        </Modularity:ModuleCatalog>
        

        bootstrapper.cs

        protected override IModuleCatalog CreateModuleCatalog()
        {
            return Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(
                new Uri("/ProjectNameHere;component/XamlCatalog.xaml", UriKind.Relative));
        }
        

        不要忘记将ModuleA.dll 文件复制/粘贴到项目的根目录,因为您在XamlCatalog.xaml 文件中引用它。

        从 App.config 文件注册/加载

        bootstrapper.cs

        protected override IModuleCatalog CreateModuleCatalog()
        {
            return new ConfigurationModuleCatalog();
        }
        

        在“App.config”中:

        <?xml version="1.0" encoding="utf-8" ?>
        <configuration>
          <configSections>
            <section name="modules" type="Prism.Modularity.ModulesConfigurationSection, Prism.Wpf"/>
          </configSections>
          <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
          </startup>
          <modules>
            <module assemblyFile="Modules/ProjectNameHere.ModuleA.dll" moduleType="ProjectNameHere.ModuleA.ModuleAModule, ProjectNameHere.ModuleA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" moduleName="ModuleA" startupLoaded="true" />
            <module assemblyFile="Modules/ProjectNameHere.ModuleB.dll" moduleType="ProjectNameHere.ModuleB.ModuleBModule, ProjectNameHere.ModuleB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" moduleName="ModuleB" startupLoaded="true" />
            <module assemblyFile="Modules/ProjectNameHere.ModuleC.dll" moduleType="ProjectNameHere.ModuleC.ModuleCModule, ProjectNameHere.ModuleC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" moduleName="ModuleC" startupLoaded="true" />
          </modules>
        </configuration>
        

        我从Prims Introduction course on Pluralsight 获得此信息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-01
          • 2011-01-13
          • 1970-01-01
          • 2011-08-28
          • 1970-01-01
          相关资源
          最近更新 更多