Question

We are working on a new application that uses C#, WPF4, Prism4 and MEF. The application comprises a main shell window which defines a grid with some splitters and five regions, and a number of separate modules that contribute UI functionality in to the various regions through view discovery and view injection. All standard stuff, nothing exotic. The application is very basic and everything works fine, i.e. the modules correctly contribute their views in to the shell's regions at run time.

We also have a requirement to host the same shell (and UI from the contributing modules) in to a large legacy MFC application we have. Here's where we're having problems. The WPF/MFC interop code (using HwndSource) seems to be working fine, as evidenced by the fact that the shell gets displayed correctly as a child of the parent MFC CView and has basic functionality like a grid splitter that is defined in the shell itself. However, none of the regions in the shell are being populated with views defined in the Prism modules. Debugging shows that the modules are indeed being loaded, however, the IRegionManager instance that gets injected in to each module contains zero regions for the module to add its views in to. It's as if Prism is not aware that the shell defines any regions at all, consequently, attempts to add views in to these "non-existent" regions fail.

We derived a new custom bootstrapper class that our MFC code calls the Run() method on. This bootstrapper class is identical to its equivalent in the standalone application (which works fine), the only difference is that we no longer override the InitializeShell() method, we just rely on the base class implementation. Typically this method is overridden to set the Application.Current.MainWindow to the shell and then show the shell, however, in our case there is no current application because we're hosted inside an MFC app. Various attempts at overriding the Bootstrapper's run functionality to yield control back to the MFC app to display the shell at the appropriate time have failed (failed in the sense that the shell's regions are still unpopulated, but the shell still displays).

Has anybody successfully used Prism 4 (specifically, got shell regions populated) within an MFC application? Any advice on how to host a Prism-enabled shell with regions in an MFC CView and have the MFC application initiate the bootstrapping process would be appreciated. Thanks.

Était-ce utile?

La solution

Okay, I figured it out. Painstakingly stepping through the Prism code, I came across a method on the RegionManager called OnSetRegionNameCallback(). This method conditionally calls CreateRegion() based on the result of another method call, IsInDesignMode(). If we are not in design mode, a region is created, otherwise no region is created. Closer examination of IsInDesignMode revealed that three separate tests are made to determine if we are in "design mode" or not, and if any of them are true, it is considered that we are in design mode. One of these checks was if Application.Current == null. Of course, in the context of an MFC application, Application.Current is indeed null, so the determination (erroneously) was that we were in design mode, and therefore no regions were ever created.

Once I realized this, further internet searches showed a number of other people have run in to the same problem. Indeed, there is even an issue logged in the Prism section of CodePlex (work item #3552) relating to this exact issue dating back to January 2009. Contributors to this work item also suggests a work around of creating a dummy application just to pass the "are we in design mode?" check. Please reference the work item for more details. I implemented a similar workaround and was then able to successfully host my Prism-enabled shell and its contributing modules in an MFC CView in an MFC application.

Thank you to those who blazed this trail before me and identified and proposed a workaround. You have saved me a lot of time!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top