在MFC CView中托管时未填充Prism shell区域

时间:2012-02-13 15:09:00

标签: shell mfc prism regions

我们正在开发一个使用C#,WPF4,Prism4和MEF的新应用程序。该应用程序包括一个主shell窗口,它定义了一个带有一些分割器和五个区域的网格,以及许多单独的模块,它们通过视图发现和视图注入为各个区域提供UI功能。所有标准的东西,没有异国情调应用程序非常基础,一切正常,即模块在运行时正确地将它们的视图提供给shell的区域。

我们还要求将相同的shell(以及来自贡献模块的UI)托管到我们拥有的大型遗留MFC应用程序中。这就是我们遇到问题的地方。 WPF / MFC互操作代码(使用HwndSource)似乎工作正常,因为shell作为父MFC CView的子项正确显示,并具有基本功能,如在shell本身中定义的网格分割器。但是,shell中的所有区域都没有填充Prism模块中定义的视图。调试显示模块确实正在加载,但是,注入到每个模块的IRegionManager实例包含零区域,模块可以将其视图添加到。就像Prism不知道shell根本定义任何区域一样,因此,尝试将视图添加到这些“不存在的”区域失败。

我们派生了一个新的自定义引导程序类,我们的MFC代码调用了Run()方法。这个bootstrapper类与它在独立应用程序中的等价物相同(工作正常),唯一的区别是我们不再重写InitializeShell()方法,我们只依赖于基类实现。通常会重写此方法以将Application.Current.MainWindow设置为shell然后显示shell,但是,在我们的示例中没有当前应用程序,因为我们托管在MFC应用程序中。覆盖Bootstrapper的运行功能以将控制权返回到MFC应用程序以在适当的时间显示shell的各种尝试都失败了(因为shell的区域仍未填充,但shell仍然显示,因此失败)。

是否有人在MFC应用程序中成功使用了Prism 4(特别是填充了shell区域)?关于如何在MFC CView中托管具有区域的Prism-enabled shell并让MFC应用程序启动引导过程的任何建议将不胜感激。感谢。

1 个答案:

答案 0 :(得分:2)

好的,我明白了。我精心地踩过Prism代码,在RegionManager上遇到了一个名为OnSetRegionNameCallback()的方法。此方法根据另一个方法调用IsInDesignMode()的结果有条件地调用CreateRegion()。如果我们在设计模式中,则会创建一个区域,否则不会创建任何区域。对IsInDesignMode的仔细检查显示,我们进行了三次单独的测试,以确定我们是否处于“设计模式”,如果其中任何一个都是真的,则认为我们处于设计模式。其中一项检查是Application.Current == null。当然,在MFC应用程序的上下文中,Application.Current确实为null,因此(错误地)确定我们处于设计模式,因此没有创建任何区域。

一旦我意识到这一点,进一步的互联网搜索显示其他一些人遇到了同样的问题。事实上,CodePlex的Prism部​​分(work item #3552)中甚至存在一个与此问题相关的问题,可追溯到2009年1月。该工作项目的贡献者还建议创建一个虚拟应用程序以通过“我们是否处于设计模式?”校验。请参阅工作项以获取更多详细信息。我实现了类似的解决方法,然后能够在MFC应用程序中成功托管我的支持Prism的shell及其贡献模块在MFC CView中。

感谢那些在我面前开辟这条道路并确定并提出解决方案的人。你为我节省了很多时间!