开发者

Prism 4 RegionManager loses first region when second one is added in WPF

We're using Castle Windsor and Prism 4 (Feb 2010). We're using the Windsor bootstrapper that makes Castle play nice with Prism that was released in the CompositeWPFContrib package.

I'm trying to define regions on my main Shell's XAML. If I define one region, like so:

<ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.ToolBarRegion}"
                    DockPanel.Dock="Top"/>

And then do the following in one of my Modules Initialize method:

_regionManager.Regions[RegionNames.ToolBarRegion].Add(typeof(SomeView));

...life is good.

However, as soon as I add another region in the Shell's XAML:

<ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.WorkspaceRegion}"
                    DockPanel.Dock="Bottom"/>

And then do:

开发者_如何学Go
_regionManager.Regions[RegionNames.WorkspaceRegion].Add(typeof(SomeOtherView));

...I get the error: "The region manager does not contain the ToolBarRegion region."

What gives? As soon as I comment out the second region it finds the first, when I add the second region back in it blows up, as if the RegionManager refuses to hold a collection of regions. It should be said that this is my first foray into both Castle Windsor and Prism, so it's not out of the realm of possibility that I'm missing something painfully obvious here. Any light that could be shed on this would be most helpful.


Are you sure it's DockPanel that you are adding your controls to? Maybe your container is a content control itself (kind of control that accepts only one child)?

Also, you could try register your region manager in the bootstrapper:

RegionManager.SetRegionManager(shell, this.Container.Resolve<IRegionManager>());

See the following questions:

Cannot find Region in RegionManager (using PRISM)

WPF, Prism v2, Region in a modal dialog, add region in code behind

EDIT

I looked at the sample solution (link in comments), and found out that your view injection code gets executed before main view is created. Your module initializers get called in StartRuntime->CreatePrismBootStrapper, and DisplayRootView (which creates your shell) is called later. Of course it can't find the region when the shell hasn't been created yet.

If all you want to register your subcontrols in module initialize code, view discovery is more suitable - it doesn't require your shell to be already created. View injection is better when you need to switch views based on user input (in this case making sure that containing control had been registered is up to you).

You have several options:

  1. Use view discovery - as you did in the sample solution.

  2. Create and register your Shell instance before loading your modules. base.DisplayRootView() should be able to find it in the container so It wouldn't create another. One way to do, but I'm not sure if best:

PrismBootstrapper.cs:

protected override DependencyObject CreateShell()
{
    Thor.Application.Views.ShellView view = new Thor.Application.Views.ShellView();
    _container.Register(Castle.MicroKernel.Registration.Component.For<Thor.Application.Views.ShellView>().Instance(view));
    // _container.Resolve<Thor.Application.Views.ShellView>();

    return view;
}

.3. CreatePrismBootstrapper() after base.DisplayRootView ? It doesn't work (NullPointerException on ServiceLocator and I'm not sure if it would make sense since I'm not really familiar with libraries used by you except Prism...

Hope this helps...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜