PRISM + MEF - 无法让区域正常工作

时间:2011-02-09 21:53:03

标签: c# wpf mef regions prism-4

对Prismv4和MEF来说有点新鲜。

我浏览了快速入门并试图将其中两个组合在一起,但我似乎无法让它工作。

首先,我有一个Bootstrapper来加载Shell Window。

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消息。然后我尝试在Shell窗口中创建一个Region,这样我就可以将View加载到该区域。我甚至没有把它用于甚至将其移动到外部组件上。

                  

[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视图(只是一个包含TextBlock的简单UserControl)没有被加载到该区域!我想我在这里如何加载我的地​​区有点迷失。

5 个答案:

答案 0 :(得分:8)

你可以尝试这个,它适用于我,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();
    }
}

HelloWorldView中的xaml

<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 :(得分:1)

看起来您正在尝试使用视图发现方法?

您是否尝试过以下操作:

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

答案 2 :(得分:1)

ConfigureAggregateCatalog中的bootstrapper方法需要添加view所在的程序集。将下面的行添加到方法的末尾可以让您解决当前的问题。

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

这也可以在XAML的{​​{1}}中完成。

您的ModuleCatalog课程还需要添加Views.HelloWorld属性。

答案 3 :(得分:0)

很难根据您分享的信息判断出现了什么问题。 我建议查看PRISM4附带的示例和参考实现。我想参考实现和一些调试应该可以帮助你找到问题。

答案 4 :(得分:0)

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