我们正在开发一个使用C#、WPF4、Prism 4和MEF的新应用程序。该应用程序包括一个主shell窗口,该窗口定义了一个带有一些拆分器和五个区域的网格,以及多个单独的模块,这些模块通过视图发现和视图注入为各个区域提供UI功能。都是标准的东西,没有异国情调。该应用程序非常基本,一切都很好,即模块在运行时将其视图正确地贡献到shell的区域中。
我们还需要将相同的shell(以及来自贡献模块的UI)托管到我们现有的大型遗留MFC应用程序中。这就是我们遇到的问题。WPF/MFC互操作代码(使用HwndSource)似乎运行良好,shell作为父MFC CView的子级正确显示,并且具有基本功能,如在shell中定义的网格拆分器,这一事实证明了这一点。但是,壳中的任何区域都没有填充Prism模块中定义的视图。调试显示模块确实正在加载,然而,注入到每个模块中的IRegionManager实例包含零个区域供模块添加视图。就好像Prism根本不知道shell定义了任何区域,因此,将视图添加到这些"不存在"的区域的尝试失败了。
我们派生了一个新的自定义引导程序类,MFC代码在该类上调用Run()方法。这个引导程序类与独立应用程序中的等效类相同(工作正常),唯一的区别是我们不再重写InitializeShell()方法,我们只依赖基类实现。通常情况下,此方法被重写以将Application.Current.MainWindow设置为shell,然后显示shell,但是,在我们的情况下,没有当前应用程序,因为我们托管在MFC应用程序中。覆盖引导程序的运行功能以将控制权交还给MFC应用程序以在适当的时间显示外壳程序的各种尝试都失败了(失败的原因是外壳程序的区域仍然未填充,但外壳程序仍然显示)。
有人在MFC应用程序中成功使用Prism 4(特别是填充外壳区域)吗?任何关于如何在MFC CView中托管具有区域的启用Prism的shell并让MFC应用程序启动引导过程的建议都将不胜感激。谢谢
好吧,我想明白了。在艰难地浏览Prism代码时,我在RegionManager上发现了一个名为OnSetRegionNameCallback()的方法。此方法根据另一个方法调用IsInDesignMode()的结果有条件地调用CreateRegion()。如果我们在设计模式中而不是,则会创建一个区域,否则不会创建任何区域。对IsInDesignMode的仔细检查表明,我们进行了三次单独的测试,以确定我们是否处于"设计模式",如果其中任何一次都是真的,则认为我们处于设计模式。其中一项检查是Application.Current==是否为null。当然,在MFC应用程序的上下文中,application.Current确实为null,因此(错误地)确定我们处于设计模式,因此从未创建任何区域。
一旦我意识到这一点,进一步的互联网搜索显示,许多其他人也遇到了同样的问题。事实上,CodePlex的棱镜部分甚至记录了一个与2009年1月的确切问题有关的问题(工作项目#3552)。该工作项的参与者还建议创建一个虚拟应用程序,以通过"我们处于设计模式吗?"检查。有关更多详细信息,请参阅工作项。我实现了一个类似的解决方案,然后能够成功地在MFC应用程序的MFC CView中托管我的启用Prism的shell及其贡献模块。
感谢那些在我之前开辟这条道路并确定并提出解决方案的人。你帮我节省了很多时间!