3

When I look Prism Navigation QuickStart demo, it uses Mef Bootstrapper and use IPartImportsSatisfiedNotification interface in Shell.xaml.cs file to load default view into the Shell Region as following.

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

In my project, I use Unity Bootstrapper and try to reference this demo for loading default view. As expected, it totally does not work.

Please, share me suggestions and some recommendations on "How to inject Default View into Shell Region with Unity Bootstrapper".

Steve.NayLinAung
  • 5,086
  • 2
  • 25
  • 49

4 Answers4

4

Assuming you have a CreateModuleCatalog override in your bootstrapper, you use it to add a module to the catalog.

catalog.AddModule(typeof(YourModule));

In the YourModule Initiaize override, register the view you want displayed like below.

Using view discovery:

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

OR

Using view injection (if you want a little more control, or need a scoped region, etc.):

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

This injection method needs you have to a reference to the region manager, and you have registered the view with the Unity container, and you have a reference to the container

As long as the YourRegion region is in your Shell xaml, and is visible at runtime, the YourView will show in it.

The Hello World quick start shows this too, and uses the Unity container.

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

R. Richards
  • 24,603
  • 10
  • 64
  • 64
3

Just add the view to the region in your Module.Initialize in which the view is coming from.

  • 1
    what if View is also used for navigation purpose? – Vishal Jun 23 '16 at 14:36
  • I mean I want to load all the modules before shell is shown. So, that I can get good speed when application runs. I have already taken a look at this answer: http://stackoverflow.com/a/5403079/2284240. But I don't know how to initialize Modules. – Vishal Jun 23 '16 at 14:38
2

I have encountered this problem If you use prism.Unity, wpf

you can set

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

after add new class for "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;
        }
    }
}

and you need a interface to find the "RegionManager"

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

last,Tell the program that you need a default view,

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

Ideas and solutions are from : enter link description here

Through this example, you can get a default view of the Navigate

zyqcome z
  • 73
  • 1
  • 6
0

You've to load/register your modules. You can do this in many ways.

Register/Load in Code

In the bootstrapper.cs:

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

Register/Load from Directory

In the bootstrapper.cs:

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

Create the Modules directory in the bin\Debug directory and copy/paste the ModuleA.dll file to this directory.

In the ModuleAModulle.cs you can define the module name and initialization method:

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

Register/Load from XAML File

Add a new Resource Dictionary to your shell project and set the build action to Resource. (In this example it's called 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>

In the bootstrapper.cs:

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

Don't forget to copy/paste the ModuleA.dll file to the root of the project, because you're referencing to it in the XamlCatalog.xaml file.

Register/Load from App.config File

In the bootstrapper.cs:

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

In the '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>

I've got this information from the Prims Introduction course on Pluralsight.

kipzes
  • 694
  • 2
  • 10
  • 27