Dynamic Views/Skins

Topics: Prism v4 - Silverlight 4
Feb 22, 2012 at 11:37 PM

Hello All,

I am currently attempting to create a mechanism whereby the user can select a particular skin for a Prism application.  Currently this is done with a ContentControl at the Shell level, with bindings set as such:

<ContentControl Content="{Binding SelectedProfile.Content}" ContentTemplate="{Binding SelectedProfile.ContentTemplate}" />

I have a ComboBox which the user can drop down to select a different view profile.

The problem occurs upon the 2nd selection.  The ViewProfile.Content for the initial ViewProfile and the second ViewProfile.Content both have controls with the same region name assigned via the attached property RegionManager.RegionName="regionname".  When the 2nd ViewProfile.Content is set as the content to the Shell's ContentControl.Content property, the RegionManager.RegionName gets assigned a second time, but instead of simply attaching the control to the already-created region, it appears that Prism attempts to recreate the Region from scratch, resulting in a very ugly ArgumentException.

What is the best way of ensuring Regions are only created once and allow this scenario to work as expected? :)

Thank you,

Michael

Developer
Feb 24, 2012 at 6:37 PM

Hi Micheal,

If I understood your scenario correctly, you have two or more contents (for example, content1 and content2) that contain a region with the same name. It seems that, when content1 is set as the content of the Shell's ContentControl.Content property, the Shell's RegionManager "finds" the content1's region and registers it. Then, when the content2 is chosen, the Shell's RegionManager "finds" the content2's region and tries to register it; however, as this region has the same name that the content1's region, the RegionManager seems to be raising an exception claiming that a region with that name already exists.

Based on my understanding, this kind of problem could addressed by the use of scoped region managers (that means that each "content" would have its own RegionManager instead of using the Shell's RegionManager). Usually, you could create a scoped region manager for a view doing something like this:

bool createRegionManagerScope = true;
IRegionManager scopedRegionManager = mainRegion.Add(content, null, createRegionManagerScope);

However, if I understood you scenario correctly, you are not injecting the contents in a region but simply exposing the "content" in the SelectedProfile.Content property and bind it to the Content property of the control. In this scenario, I believe a possible approach could be to set the RegionManagerProperty attached property of each view to a new RegionManager manually before exposing it through the SelectedProfile.Content. Like this, the regions of each "content" should not be registered in the Shell's RegionManager.

You can find more information about scoped region managers in the following section of Prism's documentation:

Please, let us know if we have misunderstood your scenario.

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Feb 24, 2012 at 6:41 PM

That is great, Damian.  That's exactly what I'm looking for.  I ended up hacking it to auto-generate regions based on the number of times the unique region-name was set.  I will go back and use this method instead.  Thanks again!