Prism shell regions not populated when hosted in an MFC CView - shell

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.

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!

Related

What effect does declaring the various <accessor style> tags in SDEF have?

When I declare elements in the .sdef file for my scriptable application, I have the option to declare various accessors, like this:
<accessor style="id"/>
<accessor style="index"/>
However, I wonder what consequence these declarations have. So far, I could not make out any changes of behavior in my test scripts whether I add or remove accessors for index and id as long as I implement the necessary methods.
So, how do these affect anything? Are they only for documentary purposes, such as what is shown in the dictionary of the Script Editor?
Or does the scripting engine actually behave differently in certain cases depending on these declarations?
So far, I only noticed one behavior that affects them: Script Debugger appears to use them to decide how to browse values in its Explorer. But I doubt Apple added these declarations only for the purpose of this application.
AppleScript does not validate against these settings in your SDEF. However, other tools may. For instance, my Script Debugger application uses this information to control the object access options presented to the user in its Explorer viewers. Various AppleEvent bridges may also use this information to control the kinds of object access they provide to their host scripting languages. An example from the distant past was my JavaScriptOSA project which bridged AppleEvent access into JavaScript. It used the key form settings to control the keys one could use when accessing element objects.

Using Netbeans to create a project

I have been using JGrasp for about 3 years which I am use to creating classes, Main classes, GUI classes which would be contained in the same folder in order to compile.
Now I started using NetBeans, and I pretty new to creating projects, creating the types of classes I will be using.
So my question is.. If i was to create a simple project which involves 3 classes, Person (super class), Employee (which inherits Person) and a Date class (which is associated with the Employer class).
I then also create a simple Gui interface on top of this class structure in order to take in details based on Person details and/or Employee details, and then a choice to display them on text area. The GUI contains 2 classes (UserDetails (takes in the details, and DisplayDetails (displays the details).
Would all this be contained into 1 project? And would the normal classes be contained a package different from the GUI classes?
Thanks, much appreciated.
With 5 classes, you can get by without a package structure. But you might aw well start thinking about a higher level of organization to your program code.
Put your data objects in one package--com.you.program.data
Put your GUI in at least one other package--com.you.program.ui
Main program could be in com.you.program or com.you.program.main or, if it is easier, just put the main in the UI package if its mostly just firing up the UI.
Note that com.you is, theoretically your webside backwards and 'program' is the name of the program you are working on.
NOTE
There is a theoretical discussion that goes on about whether to divide the business logic of the application from the UI that connects it to the user. Doing this makes it easier to put a different UI on the front of things and allow, for example, a Swing interface for users running on their desktops/laptops and a Web interface for users running browsers on their tablets and phones.
Its not a bad idea and one way to isolate that is to make two projects in your IDE. One holds the UI layer code and one holds the Business layer code. This is a well defined pattern and works well.
Another way to isolate the UI and business layers is to use packages but the IDE will not enforce any dependency management. But on a small project it does work well. You have to be disciplined. (And never forget how small projects grow into large ones with time and they do it unexpectedly.)
If you use projects, make sure there are no dependencies where the Business layer project uses the the UI layer without implementing a well defined pattern, perhaps an Observer (the GOF pattern). The UI layer, however, can and will be dependent on the Business layer. You can also enforce this during the stand-alone build process with a tool like Maven or Gradle, that excels at this.
No matter how you do it, you have to think about what is business logic. If you add some Javascript code to a browser or some code to a Swing GUI or a phone app to check that the phone number is a valid format for the country, its probably not going to bite you. If, however, you add code to the front end, in a similar way, that directly calls the phone number database to verify the first few digits are valid, you have stepped over the line. In those cases, that logic needs to be in the Business section and the UI part needs to call it to check that phone number. This is always a hard question to resolve with lots of edge cases.

cant understand the concept of the many projects in one solution in vs2010

I seem having difficulty in understanding the reason behind the need of having many projects inside one solution (in my case visual studio 2010 with c#).
The only use that comes to mind is if I am creating a new classes I can test them in a console application first, then add another project to the solution to use these classes with the project that I want.
kindly guide me to the correct way, thanks.
A typical project might have a UI, a data layer, a services layer, and a domain layer, as well as some tests. A typical arrangement would be for each of these to exist as their own project file. The solution would contain all of these projects so that you can make modifications and debug different parts of the app at once.
If you're just starting out, you probably cram all of this stuff into one project. That's fine for learning, but is an absolute mess for maintainability and reusability.
There are 3 main reasons that immediately come to mind for splitting your solution into multiple projects: Reuse, Encapsulation, and Project-specific settings.
Reuse
You may have a Utilities project that is shared between more than one solution. You may also have data access and business rules that are defined in class libraries, but are shared between multiple UI projects, such as having a business application that has a web interface, a desktop interface, and web services. They all need to share the same logic and data model, so you wouldn't want to replicate it in each solution separately.
Encapsulation
Another reason is to achieve encapsulation, one of the main principles of OOP. Your classes may have internal methods and properties (or the classes themselves may even be defined as internal), which makes them only visible to other classes in the same project. If it's there to achieve a specific purpose but not something that should be accessible to all, by splitting your classes across separate projects you can make those properties, methods, and classes visible to your classes, but hidden outside the scope of your project.
Project-specific settings
There are certain project types that behave completely differently from one another. A Web Project is different from a Windows Forms app, which is completely different than a WPF app. This kind of goes along with #1 and trying to achieve code reuse; since you can't have a single project that is a website AND a Windows Forms app AND a WPF app, you create each UI as its own project and put as much logic as possible into a separate project that can be shared between all of the UI projects.
A couple possible reasons off the top of my head:
a project may be useful in more than one solution
simple organization utility - just like you might have classes in separate files even though a single source file can hold multiple classes just fine.

Windows Workflow Foundation 4.0 Designer Rehosting with Custom Activities

I have several WF 4.0 workflows that I have created for an application my company is developing. Some of these workflows are simple, and some are very complex (i.e. many steps, several different types of activities, custom activities). For many of these workflows, I have created several custom code activities to support some internal process types.
The workflows work great and we have had very few problems when it comes to maintaining them within VS 2010. We now want to move that responsibility off to our business users, so I have created a WPF application to rehost the WF designer (according to the MS samples). My problem is that when I open one of the workflows that contains custom code activities, those activities are represented as red boxes with the error message of "Activity could not be loaded because of errors in XAML."
I have done research and have found several posts that mention that this is usually a problem with namespacing and referencing. The rehosted designer is in a namespace similar to this:
Company.Application.Workflow.Designer
And the custom code activities are contained within a separate custom workflow library, which I have included as a reference in the designer project. The library's namespace is similar to this:
Company.Application.Workflow.Data.Activities
As I have mentioned, the library is set as a reference in the designer's project, and I see it being copied to the output when I build the project. I have also included the reference in the XAML of the main designed application.
What am I missing?
There could be a lot of things wrong here. For one did you set the LocalAssembly when using the XamlXmlReader? See here for an example. Another problem could be your activities loading just fine but the related activity designers not being found. You can also use the AppDomain.CurrentDomain.AssemblyResolve event to see what assemblies are being loaded and failing. Or even better use Fuslogvw.exe for the same purpose.

What unloads the modules when a vb6 program terminates

The proper way to end a vb6 program is to do something like this :
Dim frm As Form
For Each frm In Forms
Unload frm
Next frm
end
That takes care of forms, what takes care of modules in memory?
There is no need to explicitly unload modules in VB6. They are unloaded automatically when the last form is unloaded. The language doesn't support references to standard modules at all, only to the (global) functions and variables defined therein. Since you can't reference the module, you can't unload them either.
Don't use End, you don't need to (ever). Then all memory gets freed properly.
Even using End, memory should be freed automatically. There was a rumor that some class instances are forgotten and don't get terminated correctly, despite reference counting. Thus, it's been established as best practice to set all object instances to Nothing explicitly (especially, but not limited to instances allocated in modules). I've never seen any confirmation that this is actually true (it might still be, though!).
If by "module" you mean static .BAS modules (they're all modules: Forms, Classes, UserControls, etc.) you don't need to "unload" them because they're static.
Most other module types are dynamically loaded. In the case of Forms typically via the predeclared global reference variable with the same name and type as the Form class (yes, a Form is a kind of class).
Note that if you use global variables then you should check if any of them need to get cleaned up. If so you should have a CleanUp method of your module and call that during the unload event of your main form. Another gotcha is sometimes the ORDER of how you unload things is important. By doing an explicit cleanup you can control that.
In VB6 you should rarely use END. If you have any circular references the program will remain as a process chewing up resource causing various strange bugs when you fire it up again. With COM objects is very easy to in inadvertently setup a chain of object thats is circularly linked.
End exists as a compatibility holdover from previous version of QuickBASIC and Visual BASIC. It did not start causing major problems until VB 4.X introduced the ability to create classes. It started gaining attention in 5.X.
Prior to this one of the only ways to make this happen in VB 3.X is to have two forms set references to each other.
The method of Unloading ALL MODULES on exit had resolved a funny bug for retrieving an exit code with API call ExitProcess()

Resources