PRISM + MEF - Не удается заставить регионы работать должным образом - PullRequest
4 голосов
/ 10 февраля 2011

немного нового для Prismv4 и MEF.

Я прошел QuickStarts и попытался объединить два из них вместе, но я не могу заставить его работать.

Во-первых,У меня есть Bootstrapper для загрузки окна оболочки.

public sealed class ClientBootstrapper : MefBootstrapper
{
    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();

        //Add this assembly to export ModuleTracker (Shell is in this Assembly).
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
    }

    protected override DependencyObject CreateShell()
    {
        return Container.GetExportedValue<Shell>();
    }

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

        Application.Current.MainWindow = (Window)Shell;
        Application.Current.MainWindow.Show();
    }
}

Это работало нормально.Было открыто окно Shell и появилось приятное сообщение Hello World.Затем я попытался создать регион внутри окна оболочки, чтобы я мог загрузить вид в этот регион.Я даже не понял, как это работает, чтобы даже взглянуть на перемещение его во внешнюю сборку.

[ModuleExport(typeof(HelloWorldModule), InitializationMode = InitializationMode.OnDemand)]
public class HelloWorldModule : IModule
{
    [Import(AllowRecomposition = true)]
    private IRegionViewRegistry regionViewRegistry;

    [ImportingConstructor()]
    public HelloWorldModule(IRegionViewRegistry registry)
    {
        this.regionViewRegistry = registry;
    }

    public void Initialize()
    {
        regionViewRegistry.RegisterViewWithRegion("PrimaryRegion", typeof(Views.HelloWorldView));
    }
}

Представление HelloWorld (просто простой UserControl, содержащий TextBlock)загружается в регион!Я думаю, что я немного потерял здесь, как загрузить в моих регионах.

Ответы [ 5 ]

8 голосов
/ 16 сентября 2011

Вы можете попробовать это, и он работает для меня, класс Module выглядит следующим образом:

[ModuleExport(typeof(HelloWorldModule))]
public class HelloWorldModule : IModule
{

    [Import]
    private IRegionManager regionManager;

    public void Initialize()
    {
        Uri viewNav = new Uri("HelloWorldView", UriKind.Relative);
        regionManager.RequestNavigate("PrimaryRegion", viewNav);
    }
}

Класс View выглядит следующим образом:

[Export("HelloWorldView")]
[PartCreationPolicy(CreationPolicy.Shared)]
public partial class HelloWorldView : UserControl
{
    public HelloWorldView()
    {
        InitializeComponent();
    }
}

xaml в HelloWorldView

<UserControl x:Class="HelloWorldModule.HelloWorldView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <TextBlock>Hello World</TextBlock>
</Grid>
</UserControl>

Вам понадобится

protected override void ConfigureAggregateCatalog()
    {
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstapper).Assembly));
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(HelloWorldModule.HelloWorldModule).Assembly));

    }
1 голос
/ 12 февраля 2011

Похоже, вы пытаетесь использовать подход обнаружения вида?

Вы пробовали следующее:

    [ModuleExport(typeof(HelloWorldModule), InitializationMode = InitializationMode.OnDemand)]
public class HelloWorldModule : IModule
{
    private IRegionManager regionManager;      

    [ImportingConstructor]
    public HelloWorldModule(IRegionManager regionManager)
    {
        this.regionManager = regionManager;
    } 

    public void Initialize()
    {
        this.regionManager.RegisterViewWithRegion("PrimaryRegion", typeof(Views.HelloWorldView));
    }
}
1 голос
/ 13 марта 2011

Ваш метод ConfigureAggregateCatalog в вашем bootstrapper должен добавить сборку, в которой находится ваш view. Добавление строки ниже в конец метода должно помочь вам преодолеть текущую проблему.

this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Views.HelloWorld).Assembly));

Это также можно сделать в XAML в ModuleCatalog.

Вашему классу Views.HelloWorld также потребуется добавить атрибут [Export].

0 голосов
/ 27 апреля 2011
public class ModuleC : IModule
{
    #region IModule Members

    /// <summary>
    /// Initializes the module.
    /// </summary>
    public void Initialize()
    {
        /* We register always-available controls with the Prism Region Manager, and on-demand 
         * controls with the DI container. On-demand controls will be loaded when we invoke
         * IRegionManager.RequestNavigate() to load the controls. */

        // Register task button with Prism Region
        var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
        regionManager.RegisterViewWithRegion("TaskButtonRegion", typeof(ModuleBTaskButton));

        /* View objects have to be registered with Unity using the overload shown below. By
         * default, Unity resolves view objects as type System.Object, which this overload 
         * maps to the correct view type. See "Developer's Guide to Microsoft Prism" (Ver 4), 
         * p. 120. */

        // Register other view objects with DI Container (Unity)
        var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
        container.RegisterType<Object, ModuleBRibbonTab>("ModuleBRibbonTab");
        container.RegisterType<Object, ModuleBNavigator>("ModuleBNavigator");
        container.RegisterType<Object, ModuleBWorkspace>("ModuleBWorkspace");
    }
}
0 голосов
/ 11 февраля 2011

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

...