Design considerations for nested region

Topics: Prism v4 - WPF 4
Oct 29, 2012 at 7:25 PM

Having some issues designing an application with a model hierarchy. We have a Contract object, which can have X number of Projects. The project can have X number of Lines. I'm using MEF. On my Shell, I have a ContentControl marked as "ContractRegion". In that, I intend to load a ContractView. Inside of the ContractView, I want to have a ListBox that lists all projects and a "ProjectRegion" that I can activate a ProjectView when a project is selected from the ListBox.

Currently, I have a "controller" class that activates the ContractView into the ContractRegion. Then, when I select a Project, the ContractViewModel notifies the controller to load the ProjectView into ProjectRegion. OK...this works, but now I don't know how to destroy these viewmodels. I have a test button to unload the ContractView from the ContractRegion...but the ContractViewModel/ProjectViewModel objects still exist...they're still subscribed to the EventAggregator.

Can someone help me figure out how to destroy the view/viewmodels on-demand (or at least guarantee they are designated for garbage collection). Could someone take a look at my small sample project and help me?

Oct 29, 2012 at 7:27 PM
Edited Oct 29, 2012 at 7:28 PM

Sample Project:!143&authkey=!AOqMIDTbb3anLio

Oct 29, 2012 at 8:53 PM


If your view model does not require to perform any specific "clean-up" when being destroyed, I believe you could take advantage of the IRegionMemberLifetime interface and the RegionMemberLifetimeBehavior to remove the view and it's view model automatically when deactivated.

Basically, when a view / view model that implements the IRegionMemberLifetime interface is deactivated in a Region the RegionMemberLifetimeBehavior will check its KeepAlive property. If this property returns false, the behavior will automatically remove the view / view model from the Region, and as the Region will no longer hold a reference to the view / view model, it will be marked to be garbage collected unless another object of your application is holding a strong reference to it.

Based on my understanding of your scenario, you could implement the IRegionMemberLifetime interface in your ProjectViewModels and set its KeepAlive property to false. If the ProjectRegion is a ContentControl, when you inject a ProjectView in it any other previous ProjectViews in the ProjectRegion will be marked as deactivated (this is the default behavior when using a ContentControl as a Region, as there can be only one active view.) Then, the deactivated ProjectView (and its view model) will be removed from the ProjectRegion by the RegionMemberLifetimeBehavior and, if it is not being referenced by any other object in your application, it should be marked to be garbage collected automatically.

Take into account that even if an object is marked to be garbage collected, it will still listen to the events from the EventAggregator until the garbage collector destroys it. In order to check if the views / view models are being marked to be garbage collected properly, you could invoke the GC.Collect() method before publishing the testing event in order to avoid false positives (remember that the CG.Collect() method should only be used with testing purposes as its usage is not recommended in a common application.)

I hope this helps,

Damian Cherubini

Oct 30, 2012 at 12:43 PM
Edited Oct 30, 2012 at 12:54 PM

Thank you for your reply. If I have a ProjectView loaded into my ProjectRegion and choose to deactivate my ContractView, do I have to do anything special to unload the ProjectView as well, or will it automatically unload?

Oct 30, 2012 at 6:57 PM


In that case I believe you could find the ClearChildViewsRegionBehavior provided in Prism 4.1 useful. By using this behavior, when removing a view from a region, if that view has a nested region inside it, that region should be removed from its RegionManager; and as the region is no longer attached to the RegionManager it should be garbage collected together with the views it contains.

Hence, by using the ClearChildViewsRegionBehavior, when the ContractView is removed from the ContractRegion, its ProjectRegion will be removed from the RegionManager and if no strong reference is made to that region, the ProjectRegion will be marked to be garbage collected along with the ProjectViews inside it.

You can find more information about how to use the ClearChildViewsRegionBehavior in the following section of the Prism documentation:


Damian Cherubini

Oct 30, 2012 at 7:22 PM

OH that worked perfectly! Thanks. I had tried to implement my own version of that because I didn't realize it was built into 4.1, and it didn't work. But switching to the built-in version fixed it. Thanks again!