Prism 2.2, Some regions are MIA in RegionManager when using databinding

Topics: Prism v2 - WPF 3.5
Jul 7, 2010 at 1:58 PM

Hello

 

I am having some problems with understanding how the region manager works

We are building a modular application, where some of the views can be dynamically shown or hidden by the user. To achieve this we have created a number of regions which we behind the scenes activate or de-activate, according to the user's choices in a menu.

The regions with the views are being dynamically created through a data template in xaml, and looks something like this:

<UserControl x:Class="Overview"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cal="http://www.codeplex.com/CompositeWPF">
    <UserControl.Resources>
        <Style TargetType="{x:Type ItemsControl}" x:Key="OverViewItems">
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <ContentControl cal:RegionManager.RegionName="{Binding RegionName}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Grid>
        <Grid>
            <ItemsControl Style="{StaticResource OverViewItems}" ItemsSource="{Binding Views}"/>
        </Grid>
    </Grid>
</UserControl>

The ItemsSource is an ObservableCollection “Views”, where each items has the property “RegionName” (a GUID).
All this seems to work just fine (ie. the controls are being displayed correctly) - however, when I later ask the RegionManager for one of the regions, it responds that it does not contain the region.

We have created a view model to achive the goal of activating or de-activating the regions, using the following event handler code:

public void PortletChanged(Portlet changedPortlet)
{
    if (m_RegionManager.Regions.ContainsRegionWithName(changedPortlet.RegionName))
    {
        if (changedPortlet.Enabled == false)
        {
            var views = m_RegionManager.Regions[changedPortlet.RegionName].Views;
            m_RegionManager.Regions[changedPortlet.RegionName].Deactivate(views.FirstOrDefault());
        }
        else
        {
            var views = m_RegionManager.Regions[changedPortlet.RegionName].Views;
            m_RegionManager.Regions[changedPortlet.RegionName].Activate(views.FirstOrDefault());
        }
    }
}

Do anyone have an idea on how to solve this problem, or even how to proceed with debugging it. Despite having spent quite a lot of time with breakpoints deep in the Prism code, I haven't been able to fully get an overview of what is going on underneath the Prism covers. It looks to me like a new RegionManager is being created when the Overview user control is being created and the data binding occurs, instead of just using the default RegionManager.
We have tried doing the same thing in code, and in that case we have no problems finding the regions again, when calling the m_RegionManager.Regions.ContainsRegionWithName(changedPortlet.RegionName) method.
If I'm correct in my assumptions that a new region manager is being created, is there any way to prevent this from happening? Or should I go in a different direction with achieving the problem I'm trying to solve?

Any help at all will be greatly appreciated

Thanks
Jul 8, 2010 at 4:21 PM

Hi,

I checked this and found the behavior you described as well. As it seems to be an issue, I would suggest to you for posting it in the issue tracker, so the Prism team will be notified.

Based on this forum thread, the RegionManager can’t find the region you’ve defined because it’s located inside a DataTemplate, and the FindRegionManager method inside the RegionManagerRegistrationBehavior cannot find regions inside DataTemplates.

I do not know your exact scenario, but I think you could manage it by adding/removing views from a particular region. You could achieve such thing by using:

Both options could allow to you to dynamically add views depending on the users’ choices.  

Please let me know if this helps.

Fernando Antivero
http://blogs.southworks.net/fantivero

Jul 9, 2010 at 11:45 AM

Hi Fernando

 

Thank you for your reply.

I have already considered using both options, and have had injection up and running in prototypes. But using the activate / de-activate features of the regions seemed like a much cleaner design to me.

(Aside from generally making your applications a nightmare to debug when you use databinding like this, I really love the powerful databinding features of WPF)

 

You suggest that I create a new issue in the issue tracker - But if I read the thread you are linking to correct, it seems to me like the behavior I'm seeing is actually intended (last post in the Thread, from Matias)?

Although, as it looks like it's not exactly the same issue (my view are being displayed just fine on the screen, and thus the regions must be there, somewhere, just not in the RegionManager I'm looking in :),
I'll go ahead and create the issue as you suggest.

 

Thank you very much for your help :-)