当在 WPF 中添加第二个区域时,Prism 4 RegionManager 会丢失第一个区域
我们正在使用 Castle Windsor 和 Prism 4(2010 年 2 月)。我们正在使用 Windsor 引导程序,使 Castle 能够与 CompositeWPFContrib 包中发布的 Prism 很好地配合。
我正在尝试在主 Shell 的 XAML 上定义区域。如果我定义一个区域,如下所示:
<ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.ToolBarRegion}"
DockPanel.Dock="Top"/>
然后在我的模块初始化方法之一中执行以下操作:
_regionManager.Regions[RegionNames.ToolBarRegion].Add(typeof(SomeView));
...生活很好。
但是,一旦我在 Shell 的 XAML 中添加另一个区域:
<ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.WorkspaceRegion}"
DockPanel.Dock="Bottom"/>
然后执行:
_regionManager.Regions[RegionNames.WorkspaceRegion].Add(typeof(SomeOtherView));
...我收到错误:“区域管理器不包含 ToolBarRegion 区域。”
什么给?一旦我注释掉第二个区域,它就会找到第一个区域,当我将第二个区域添加回来时,它就会爆炸,就好像 RegionManager 拒绝保存区域集合一样。应该说,这是我第一次尝试温莎城堡和棱镜,所以我也有可能错过一些非常明显的东西。任何可以阐明这一点的线索都是最有帮助的。
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:
_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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您确定要向 DockPanel 添加控件吗?也许您的容器本身就是一个内容控件(一种只接受一个子控件的控件)?
另外,您可以尝试在引导程序中注册您的区域管理器:
请参阅以下问题:
在 RegionManager 中找不到区域(使用 PRISM)
WPF、棱镜 v2 ,模式对话框中的区域,在后面的代码中添加区域
编辑
我查看了示例解决方案(注释中的链接),发现您的视图注入代码在创建主视图之前执行。您的模块初始值设定项在 StartRuntime->CreatePrismBootStrapper 中被调用,并且 DisplayRootView(它创建您的 shell)稍后被调用。当然,当shell还没有创建时,它是找不到该区域的。
如果您只想在模块初始化代码中注册子控件,则视图发现更合适 - 它不需要已创建 shell。当您需要根据用户输入切换视图时,视图注入会更好(在这种情况下,确保包含控件已注册由您决定)。
您有多种选择:
使用视图发现 - 正如您在示例解决方案中所做的那样。
在加载模块之前创建并注册您的 Shell 实例。 base.DisplayRootView() 应该能够在容器中找到它,这样它就不会创建另一个。一种方法,但我不确定是否最好:
PrismBootstrapper.cs:
.3。在 base.DisplayRootView 之后 CreatePrismBootstrapper() ?它不起作用(ServiceLocator 上的 NullPointerException,我不确定它是否有意义,因为我不太熟悉除 Prism 之外的您使用的库...
希望这有帮助...
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:
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:
Use view discovery - as you did in the sample solution.
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:
.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...